unsure how to integrate expressjs backend, aws api gateway, and nextjs.
Unanswered
Champagne D’Argent posted this in #help-forum
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 
215 Replies
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:

->
![image name] (/api/image/hash)

->
![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
}
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
@Champagne D’Argent
"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

Champagne D’ArgentOP
I was pulling the data from the backend, but I face an error
Unhandled Runtime Error
Error: async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding
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.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 componentexport 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’Argent <@743561772069421169> that did not work
what is
imageDataChampagne 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
@Ray ts
"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
this only renders the image at the path /api/image/:hash
can i reference it another place such as <img url ="/api/image/:hash" />
will the reference work?
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?
@Champagne D’Argent Is it because it is a json object and not a readable stream of data?
could you show the code
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'
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’Argent however, it does not seem to populate my webpage with the actual image
it should show under
New Post:?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’Argent js
export async function GET(req:Request, { params }: { params: { hash: string } }) {
return await fetch(`http://localhost:5000/api/image/${params.hash}`)
}
do you see the image with this url
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
you need to set it to image
Champagne D’ArgentOP
should it be base64?
Champagne D’ArgentOP
I did image/*
as I am unsure what the image file will be
it could be jpg or png
@Champagne D’Argent 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'
but here is showing
application/jsonChampagne 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'
}
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
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
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
sChampagne 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
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/pngChampagne 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.bufferChampagne 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
