There are other questions related to this one, but none are specific to this particular issue.
None that I could find. None of them ask the following question:
"Why does my server-side node-fetch API work in Node Express, but it immediately falls apart on the client side, returning this error message: "Uncaught ReferenceError: body is not defined"?
I am fairly confident the server-side API returns the right response.
I have tried putting body in the headers, both as "body: body" and as "body: JSON.stringify(body).
I also tried to stringify the API response. No dice.
In the Server Side Screenshot below, Developer tools in Chrome browser indicate a successful request to the NASA server. Under Network, the payload is right. Response is also correct, with the gallery populated by image URLs from the Mars Rover chosen by the user.
In the Client Side Screenshot, however, it returns a "Reference Error: body is not defined", regardless of what I try. As shown in the image, this message becomes an "Invalid Rover Name" error from NASA, with the gallery suddenly empty of image URLs.
In the command prompt, I see similar results.
The rover is defined correctly on the server side at http://localhost:3000/userinput, after I choose a rover and click submit. When I come back to http://localhost:3000/, the same rover name logged in the command prompt suddenly changes to "undefined."
I cannot see what I am doing wrong.
I suspect the problem lies in these two lines from the server-side API.
.then(response => response.json()) // send json to client
.then(gallery => response.send({gallery})) // send gallery to browser (so I can see it)
As I thought I understood, 1) the top one returns the json response to the client side, and 2) the second one sends the response as text to the browser.
Clearly, what I see in the browser is not what the client fetch API receives, but I don't how that can be when the NASA server is returning the right response. I see the correct image URLs coming back and sent to the browser at "/userinput."
I understand the difference between server and client Node Expres, or thought I did. But I don't understand what I am doing wrong here. If it is an async problem, I don't see it.
Can anyone shed some light on the problem?
Thank you for reviewing my question.
Please Note: I received a message from Stack Overflow that I am not allowed to embed images in my questions yet.
But it has included links to those images.
I did know when I wrote the question.
Relevant Code from HTML Form:
<form action="http://localhost:3000/userinput" method="POST">
<button id="submit" name="submit">Send Images</button>
Relevant Server Side API Code:
app.use('/', express.static(path.join(__dirname, '../public')));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors("*"));
app.post('/userinput', async (request, response) => {
const rover = request.body.rover
console.log("SERVER SIDE ROVER: ", rover)
try {
const gallery = await fetch(`https://api.nasa.gov/mars-photos/api/v1/rovers/${rover}/latest_photos?api_key=DH46IQlx0gMyXPmLAgkxXDSPo2OrbIjPs8OJLj6L`)
.then(response => response.json()) // send json to client
.then(gallery => response.send({gallery})) // send gallery to browser (so I can see it)
} catch (err) {
console.log(`RESPONSE STATUs: ${response.status}`, err);
}
return response.json();
});
const port = 3000;
app.listen(port, () => {
console.log(`Server running on port${port}`);
Relevant Client Side API code:
// Single async higher-order/callback function
// Retrieves image data and update store/new state
// getRoverPhotos is Higher Order function.
// RoverPhotos as callback function.
const getRoverPhotos = async (state, fn) => {
const response = await fetch("http://localhost:3000/userinput", {
method: "POST",
headers: {'Content-Type': 'application/JSON' }
})
console.log("RESPONSE CLIENT: ", response)
const jsonImageData = await response.json()
console.log("JSON Image Data")
console.log(jsonImageData)
const ImageData = await jsonImageData.gallery.latest_photos.map(photo => {
return photo.img_src;
});
const newState = jsonImageData.gallery
updateStore(store, newState)
return ImageData
}
getRoverPhotos(store, updateStore)
Server Side Screenshot
Client Side Screenshot
Shows failed response. Gallery emptied under Developer Tools => Console