Next.js Discord

Discord Forum

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

Unanswered
Champagne D’Argent posted this in #help-forum
Open in Discord
Champagne D’ArgentOP
"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)

215 Replies

what's your image data?
like a link or a blob?
or what is it?
Champagne D’ArgentOP
its a blob
ok and you want to display the image? Or what would you like to do?
Champagne D’ArgentOP
I want to display the image using markdown by referencing as such : ![image name] (/api/image/hash)
you can just replace the path with your link like:
![%imageName%](%link%)
->
![image name] (/api/image/hash)
Champagne D’ArgentOP
How do I make the call to the backend that gives it the blob?
normally the library that you using can also replace the markdown like that
Champagne D’ArgentOP
I don't have an issue with the markdown.
I have an issue with rendering the blob or like retrieving it from the backend
normally you are able to generate a url like that and then be able to display this url
Champagne D’ArgentOP
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
🤔
Champagne D’ArgentOP
i just want the right resource to be available at that url,which is image data
hm I think I know not enought to help you here. Maybe someone else is able to help there
Champagne D’ArgentOP
@Ray could you help me out here?
@Champagne D’Argent <@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>
}
Champagne D’ArgentOP
@Ray 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})
}
Champagne D’ArgentOP
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.
@Champagne D’Argent I want to display the image using markdown by referencing as such : ![image name] (/api/image/hash)
Champagne D’ArgentOP
I want image data to be found at the path: /api/image/:hash
"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
Champagne D’ArgentOP
"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} />
}
Champagne D’ArgentOP
that would display an image. However, will I be able to reference it elsewhere in my app?
does that make sense?
wdym?
@Champagne D’Argent I want to display the image using markdown by referencing as such : ![image name] (/api/image/hash)
Champagne D’ArgentOP
i am using markdown in certain aspects of my blog site
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
you don't want to show this link http://localhost:5000/api/image/${params.hash}?
Champagne D’ArgentOP
I could do that
then I think you could just use that link for the image in markdown?
Champagne D’ArgentOP
I guess so
@Champagne D’Argent I guess so
you could create a route handler if you want to use this link![image name] (/api/image/hash)
// 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}")
}
Champagne D’ArgentOP
I was just looking at the docs!
thank you
does it work for you?
Champagne D’ArgentOP
I am still testing one minut
Champagne D’ArgentOP
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
}
Champagne D’ArgentOP
However, this is no longer a request
you didnt await
Champagne D’ArgentOP
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
@Champagne D’Argent Click to see attachment
// 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
@Champagne D’Argent Click to see attachment
wait, are you using axios or fetch
@Ray wait, are you using axios or fetch
Champagne D’ArgentOP
axios
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?
look like you didn't set the header
Champagne D’ArgentOP
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 ^
@Champagne D’Argent Click to see attachment
console.log(response)
Champagne D’ArgentOP
the response is very large and contains a lot of other details apart from the image data
however, response.data is the image data
@Champagne D’Argent the response is very large and contains a lot of other details apart from the image data
ok i guess this
 res
    .setHeader("Content-Type", response.headers["Content-Type"])
    .setHeader("Content-length", response.headers["Content-Length"])
    .send(response.data);
Champagne D’ArgentOP
{"error":{"code":"ERR_HTTP_INVALID_HEADER_VALUE"}}
@Champagne D’Argent {"error":{"code":"ERR_HTTP_INVALID_HEADER_VALUE"}}
add a console.log(headers["Content-Type"])
Champagne D’ArgentOP
console.log(response.headers['Content-Type'] ?
yes
Champagne D’ArgentOP
okay
undefined
do you know the image type?
or log this
console.log(response.headers)
Champagne D’ArgentOP
png
png for all image?
Champagne D’ArgentOP
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'
@Ray png for all image?
Champagne D’ArgentOP
I have kept it as allow all image types
oh there it is
@Champagne D’Argent I have kept it as allow all image types
  res
    .setHeader("Content-Type", response.headers["content-type"])
    .setHeader("Content-Length", response.headers["content-length"])
    .send(response.data);
Champagne D’ArgentOP
that works
however, it does not seem to populate my webpage with the actual image
Champagne D’ArgentOP
yes
correct
ok show the handler in /api/image/[hash]
the code
Champagne D’ArgentOP
there is nothing at /api/image/[hash]
didn't you recommend a route handler
yea show the code for it
Champagne D’ArgentOP
export async function GET(req:Request, { params }: { params: { hash: string } }) {
    return await fetch(`http://localhost:5000/api/image/${params.hash}`)
}
Champagne D’ArgentOP
no
i see the file data
@Champagne D’Argent Click to see attachment
change this
const response = await axios.get(AWS_URL + `/${req.params.imageID}`, { responseType: "blob" })
Champagne D’ArgentOP
I did that
nothing changed
can you show me the url from AWS_URL?
Champagne D’ArgentOP
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
Champagne D’ArgentOP
should it be base64?
@Champagne D’Argent should it be base64?
image/png
image/jpeg
base on the file
Champagne D’ArgentOP
I did image/*
as I am unsure what the image file will be
it could be jpg or png
Champagne D’ArgentOP
I just changed it give me a minut
I will shae the new headers
I don't know how you fetch the file but it should have the content-type
Champagne D’ArgentOP
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'
}
lol
Champagne D’ArgentOP
When I refresh /api/image/:hash it downloads the image
ok try it on your site
Champagne D’ArgentOP
I am a little confused right now
Champagne D’ArgentOP
It still does not work
@Champagne D’Argent It still does not work
check the error on dev console
Champagne D’ArgentOP
there appears to be no errors
nothing regarding the image or the routehandler
params is not defined
@Champagne D’Argent Click to see attachment
check the network tab
look for the request of image
Champagne D’ArgentOP
then it should work?
reload the page
and look for image response
Champagne D’ArgentOP
I changed it up a little
js 
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})
    // }
})
lol
does it work?
Champagne D’ArgentOP
no lol
it does the same thing as the comment out code
it just downloads the iamge
how do you render the image on the page?
Champagne D’ArgentOP
the console shows that image is working fine
try this on any page
<img src="/api/images/hash" />
@Champagne D’Argent Click to see attachment
yes it should work
Champagne D’ArgentOP
![Image](http://url/a.png)
this is what I am doing
pretty much
I got this from the common mark docs
Champagne D’ArgentOP
does not work
i face this error
/api/image
you add a s
Champagne D’ArgentOP
my ba
the console is fine now but the image is not rendered
@Champagne D’Argent the console is fine now but the image is not rendered
<img src="/api/images/hash" height={300} width={480} />

how about this?
Champagne D’ArgentOP
still nothing
just this?
Champagne D’ArgentOP
ye
@Champagne D’Argent ye
what is the code on express now?
doing redirect?
Champagne D’ArgentOP
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
ok i know the problem
try change image/* to image/png
Champagne D’ArgentOP
one minute
@Ray just this?
Champagne D’ArgentOP
lmao api/image/acfc7a71128cd0e8d436d64fa661bd506f7eb73e677f6374d729c955cb42f3db returns this
not work?
Champagne D’ArgentOP
it actually rendered an image
this is what I see at /api/image/hash
lol
is this the actual image?
Champagne D’ArgentOP
no
it isn;t
oh I realised what the error is
I am having an error when uploading the actual image
lol
Champagne D’ArgentOP
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?
@Champagne D’Argent do you think this will work?
I think you need to provide the correct content-type
Champagne D’ArgentOP
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
@Champagne D’Argent 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
Champagne D’ArgentOP
did not wokr
any error
Champagne D’ArgentOP
no
I think the api gateway needs some work
Champagne D’ArgentOP
I think the problem lies on the API gateway. It isn't uploading my images properly