#unsure how to integrate expressjs backend, aws api gateway, and nextjs.

216 messages · Page 1 of 1 (latest)

ripe depot
#
"use client"
import axios from "axios";
import { useState } from "react";
export default async function getImage({params}) {
    [imageData, setImageData] = useState(null)
    const getImage = async () => {
        const response = await axios.get(`http://localhost:5000/api/image/${params.hash}`)
        setImageData(response.data)
    }
    getImage()
    // console.log(val.data)
    if(imageData) {return (val.data)}
}
``` I am unsure how to do I make this work. I am displaying image data to be reference by another component using markdown as such 
![image](link to component above)
hardy ledgeBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize

✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)

novel moat
#

what's your image data?

#

like a link or a blob?

#

or what is it?

ripe depot
#

its a blob

novel moat
#

ok and you want to display the image? Or what would you like to do?

ripe depot
#

I want to display the image using markdown by referencing as such : ![image name] (/api/image/hash)

novel moat
#

you can just replace the path with your link like:
%imageName%
->
![image name] (/api/image/hash)

ripe depot
#

How do I make the call to the backend that gives it the blob?

novel moat
#

normally the library that you using can also replace the markdown like that

ripe depot
#

I don't have an issue with the markdown.

#

I have an issue with rendering the blob or like retrieving it from the backend

novel moat
#

normally you are able to generate a url like that and then be able to display this url

ripe depot
#

const getAddress = (fieldName) =>{
const imageHash = imageUrls[fieldName]
return /api/image/${imageHash}
}

#

this is how I generate the URL

#

I don't have an issue with url generation

novel moat
#

🤔

ripe depot
#

i just want the right resource to be available at that url,which is image data

ripe depot
#

Unhandled Runtime Error
Error: async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding 'use client' to a module that was originally written for the server.

novel moat
#

hm I think I know not enought to help you here. Maybe someone else is able to help there

ripe depot
#

@spare crescent could you help me out here?

spare crescent
# ripe depot <@743561772069421169> could you help me out here?

you need to fetch the data inside a useEffect if you are using client component

export default async function getImage({ params }) {
  const [imageData, setImageData] = useState(null);

  useEffect(() => {
    const getImage = async () => {
      const response = await axios.get(
        `http://localhost:5000/api/image/${params.hash}`
      );
      setImageData(response.data);
    };
    getImage();
  }, []);

  if (!imageData) {
    return <div>loading...</div>
  }

  return <div></div>
}
ripe depot
#

@spare crescent that did not work

#
"use client"
import axios from "axios";
import { useState, useEffect } from "react";
export default function getImage({params}) {
    const [imageData, setImageData] = useState(null)
    useEffect( () =>{
        const getImage = async () => {
            const response = await axios.get(`http://localhost:5000/api/image/${params.hash}`)
            setImageData(response.data)
        };
        getImage();
    }, [])

    return ({imageData})
}
spare crescent
ripe depot
#

I removed the async for the function name and that solved the issue partially

#

image data is the raw image data

#

Error: Objects are not valid as a React child (found: object with keys {data}). If you meant to render a collection of children, use an array instead.

ripe depot
spare crescent
#
"use client"
import axios from "axios";
import { useState, useEffect } from "react";
export default function getImage({params}) {
    const [imageData, setImageData] = useState(null)
    useEffect( () =>{
        const getImage = async () => {
            const response = await axios.get(`http://localhost:5000/api/image/${params.hash}`)
            setImageData(response.data)
  console.log(response.data)
        };
        getImage();
    }, [])

    return <div></div>
}
#

show me the console.log

ripe depot
spare crescent
#
"use client"
import axios from "axios";
import { useState, useEffect, useRef } from "react";
export default function getImage({params}) {
    const [loaded, setLoaded] = useState(false)
    const ref = useRef<HTMLImageElement>(null)
    useEffect( () =>{
        const getImage = async () => {
            const response = await axios.get(`http://localhost:5000/api/image/${params.hash}`)
            const blob = await response.blob()
            const url = URL.createObjectURL(blob)
            if (ref.current) {
              ref.current.src = url
              setLoaded(true)
            }
            
        };
        getImage();
    }, [])

    if (!loaded) return null

    return <img ref={ref} />
}
ripe depot
#

that would display an image. However, will I be able to reference it elsewhere in my app?

#

does that make sense?

spare crescent
#

wdym?

ripe depot
#

So the client should be able to reference the image as I have mentioned it and place the image where the image tag is created

ripe depot
#

can i reference it another place such as <img url ="/api/image/:hash" />

#

will the reference work?

spare crescent
#

you don't want to show this link http://localhost:5000/api/image/${params.hash}?

ripe depot
#

I could do that

spare crescent
#

then I think you could just use that link for the image in markdown?

ripe depot
#

I guess so

spare crescent
#
// app/api/image/[hash]/route.ts
export async function GET(req:Request, { params }: { params: { hash: string } }) {
  return fetch("http://localhost:5000/api/image/${params.hash}")
}
ripe depot
#

I was just looking at the docs!

#

thank you

spare crescent
#

does it work for you?

ripe depot
#

I am still testing one minut

#

It is returning the response object

#

the object has the following structure: {data: image data}

#
// app/api/image/[hash]/route.ts
export async function GET(req:Request, { params }: { params: { hash: string } }) {
  const response = await fetch("http://localhost:5000/api/image/${params.hash}")
  return response.data
}
ripe depot
#

However, this is no longer a request

spare crescent
#

you didnt await

ripe depot
#

it worked without the await

#

I mean I could alter my api to just return without data

#

I updated my api. let me test my referencing it in markdwon

spare crescent
# ripe depot
// app/api/image/[hash]/route.ts
export async function GET(req:Request, { params }: { params: { hash: string } }) {
  const response = await fetch("http://localhost:5000/api/image/${params.hash}")
  const buff = Buffer.from(await response.data.arrayBuffer())
  return new Response(buff, {headers: response.headers})
}

or try this

spare crescent
ripe depot
#

this is roughly what my data looks like now

#

it is pretty much the image data

#

However, when I set this as the URL for my image, it does not load the image.

#

Is it because it is a json object and not a readable stream of data?

spare crescent
#

look like you didn't set the header

ripe depot
#

this is my expressjs endpoint code

#

js res.status(200).header("Content-Type", "multipart/form-data").json(response.data)

#

i think I just need to add this ^

spare crescent
ripe depot
#

the response is very large and contains a lot of other details apart from the image data

#

however, response.data is the image data

spare crescent
ripe depot
#

{"error":{"code":"ERR_HTTP_INVALID_HEADER_VALUE"}}

spare crescent
ripe depot
#

console.log(response.headers['Content-Type'] ?

spare crescent
#

yes

ripe depot
#

okay

#

undefined

spare crescent
#

do you know the image type?

ripe depot
#

png

spare crescent
#

or log this
console.log(response.headers)

#

png for all image?

ripe depot
#

Object [AxiosHeaders] {
date: 'Sun, 07 Jan 2024 15:31:09 GMT',
'content-type': 'application/json',
'content-length': '1804118',
connection: 'keep-alive',
'x-amzn-requestid': '70a4a3a0-db12-4fcf-b68d-5d0c2b4baa55',
'x-amz-apigw-id': 'RLOFpED9CYcEBOw=',
'x-amzn-trace-id': 'Root=1-659ac3bd-230f655021fbb37d7011bb2a'

spare crescent
#

oh there it is

ripe depot
spare crescent
ripe depot
#

that works

#

however, it does not seem to populate my webpage with the actual image

spare crescent
ripe depot
#

yes

#

correct

spare crescent
#

ok show the handler in /api/image/[hash]

#

the code

ripe depot
#

there is nothing at /api/image/[hash]

#

didn't you recommend a route handler

spare crescent
#

yea show the code for it

ripe depot
#

export async function GET(req:Request, { params }: { params: { hash: string } }) {
    return await fetch(`http://localhost:5000/api/image/${params.hash}`)
}
spare crescent
ripe depot
#

no

#

i see the file data

spare crescent
# ripe depot

change this

const response = await axios.get(AWS_URL + `/${req.params.imageID}`, { responseType: "blob" })
ripe depot
#

I did that

#

nothing changed

spare crescent
#

can you show me the url from AWS_URL?

ripe depot
#

that is sensitive to my project

#

After reading some responses on stackOverflow, I have a feeling that maybe I did not set up the API gateway correctly

spare crescent
#

you need to set it to image

ripe depot
#

should it be base64?

spare crescent
#

image/jpeg

#

base on the file

ripe depot
#

I did image/*

#

as I am unsure what the image file will be

#

it could be jpg or png

spare crescent
ripe depot
#

I just changed it give me a minut

#

I will shae the new headers

spare crescent
#

I don't know how you fetch the file but it should have the content-type

ripe depot
#

Object [AxiosHeaders] {
date: 'Sun, 07 Jan 2024 15:50:45 GMT',
'content-type': 'image/*',
'content-length': '1804118',
connection: 'keep-alive',
'x-amzn-requestid': '3c9f6253-15b5-4b65-9b28-935009923a09',
'x-amz-apigw-id': 'RLQ9aHjOCYcEsWA=',
'x-amzn-trace-id': 'Root=1-659ac855-37470a8f059fe9b101b28bc1'
}

spare crescent
#

lol

ripe depot
#

When I refresh /api/image/:hash it downloads the image

spare crescent
#

ok try it on your site

ripe depot
#

I am a little confused right now

ripe depot
#

It still does not work

spare crescent
ripe depot
#

there appears to be no errors

#

nothing regarding the image or the routehandler

spare crescent
#

params is not defined

spare crescent
#

look for the request of image

ripe depot
spare crescent
#

then it should work?

#

reload the page

#

and look for image response

ripe depot
#

I changed it up a little

#
router.get('/:imageID', async (req,res) =>{
    res.redirect( AWS_URL + `/${req.params.imageID}`)
    // try{
    //     const response = await axios.get(
    //         AWS_URL + `/${req.params.imageID}`,
    //         { responseType: "blob" }
    //     )
    //     // console.log(response)
    //     console.log(response.headers)
    //     res
    //     .status(200)
    //     .setHeader("Content-Type", response.headers["content-type"])
    //     .setHeader("Content-length", response.headers["content-length"])
    //     .send(response.data);
    // }catch(error){
    //     res.status(400).json({error:error})
    // }
})```
spare crescent
#

lol

#

does it work?

ripe depot
#

no lol

#

it does the same thing as the comment out code

#

it just downloads the iamge

spare crescent
#

how do you render the image on the page?

ripe depot
#

the console shows that image is working fine

spare crescent
#

try this on any page

<img src="/api/images/hash" />
spare crescent
ripe depot
#

![Image](http://url/a.png)

#

this is what I am doing

#

pretty much

#

I got this from the common mark docs

ripe depot
#

does not work

#

i face this error

spare crescent
#

/api/image

#

you add a s

ripe depot
#

my ba

#

the console is fine now but the image is not rendered

spare crescent
ripe depot
#

still nothing

spare crescent
#

just this?

ripe depot
#

ye

spare crescent
spare crescent
#

doing redirect?

ripe depot
#

yea

#

It pretty much does the same thing that we were doing anyways

#

I just went back to our code and retried it! it does the exact same thing

spare crescent
#

ok i know the problem

#

try change image/* to image/png

ripe depot
#

one minute

ripe depot
spare crescent
#

not work?

ripe depot
#

it actually rendered an image

#

this is what I see at /api/image/hash

#

lol

spare crescent
#

is this the actual image?

ripe depot
#

no

#

it isn;t

#

oh I realised what the error is

#

I am having an error when uploading the actual image

spare crescent
#

lol

ripe depot
#

i did a test by manually uploading an image and it worked

#

however, this is my code to upload images

#
router.post("/", uploadImages.single("image"), async (req, res) =>{
     // Put an object into an Amazon S3 bucket.
     const image = req.file.buffer;
     const hash = crypto.createHmac('sha256', image)
                    .digest('hex');
        
     console.log("imagehash:",hash);
     console.log('awsurl:', AWS_URL + `/${hash}`)
   
    try{
        const response = await axios.put(
            AWS_URL + `/${hash}`,  // url
            req.file.buffer, //file body
            {
                headers: {'content-type': "image/"},
            },
        )
        console.log("response", response)
        res.status(200).json({imageID: `${hash}`})
    }catch(error){
        console.log(error);
        res.status(400).json({error: error})
    }
})
#

i have to change the headers correct?

#

do you think this will work?

spare crescent
ripe depot
#
router.post("/", uploadImages.single("image"), async (req, res) =>{
     // Put an object into an Amazon S3 bucket.
     const image = req.file.buffer;
     const fileExtension = req.file.originalname.split('.').pop();
     const hash = crypto.createHmac('sha256', image)
                    .digest('hex');
        
     console.log("imagehash:",hash);
     console.log('awsurl:', AWS_URL + `/${hash}`)
   
    try{
        const response = await axios.put(
            AWS_URL + `/${hash}`,  // url
            req.file.buffer, //file body
            {
                headers: {'content-type': `image/${fileExtension}`},
            },
        )
        console.log("response", response)
        res.status(200).json({imageID: `${hash}`})
    }catch(error){
        console.log(error);
        res.status(400).json({error: error})
    }
})```
#

I added the file extension! hopefully this works

#

that still didn't work

spare crescent
# ripe depot that still didn't work
router.post("/", uploadImages.single("image"), async (req, res) =>{
     // Put an object into an Amazon S3 bucket.
     const image = req.file.buffer;
     const fileExtension = req.file.originalname.split('.').pop();
     const hash = crypto.createHmac('sha256', image)
                    .digest('hex');
        
     console.log("imagehash:",hash);
     console.log('awsurl:', AWS_URL + `/${hash}`)
   
    try{
        const response = await axios.put(
            AWS_URL + `/${hash}`,  // url
            req.file, //file body
            {
                headers: {'content-type': `image/${fileExtension}`},
            },
        )
        console.log("response", response)
        res.status(200).json({imageID: `${hash}`})
    }catch(error){
        console.log(error);
        res.status(400).json({error: error})
    }
})
#

req.file instead of req.file.buffer

ripe depot
#

did not wokr

spare crescent
#

any error

ripe depot
#

no

#

I think the api gateway needs some work

spare crescent