Node server gives me undefined when I send data - node.js

I'm trying to send data to the server but when I log it gives me undefined even tho I can log it on the client. I think I'm missing something.
Thanks in Advance!
Client
const handleSubmit = async (e) => {
e.preventDefault()
try{
const response = await axios.post('http://localhost:8000/send', {formData})
console.log(response)
} catch(error){
console.log(error)
}
}
Server
app.post('/send', async (req, res) => {
console.log(req.body)
res.send("ok")
})

//client
const handleSubmit = async (e) => {
e.preventDefault()
const config = {
"headers":{
"Content-Type":"application/json"
}
}
const body = JSON.stringify({
formData
})
try{
const response = await axios.post('http://localhost:8000/send', body, config)
console.log(response)
} catch(error){
console.log(error)
}
}
// server
const express = require("express");
const app = express();
app.use(express.json()); // this is necessary
app.post('/send', async (req, res) => {
console.log(req.body)
res.send("ok")
})
Hope it helps!

remove the object property shorthand, use just formData:
const response = await axios.post('http://localhost:8000/send', formData)

I think you might need to set a header on the request
try adding config object as a 3rd argument
const config = {
headers: {'Content-Type': 'application/json'}
}
const handleSubmit = async (e) => {
e.preventDefault()
try{
const response = await axios.post('http://localhost:8000/send',
{formData}, config)
console.log(response)
} catch(error){
console.log(error)
}
}

Related

sent file from React to Node and got empty obj

I am getting img data and send this data to the server
console.log shows that data exists
const [fileData, setFileData] = useState("");
console.log("fileData:", fileData);
const getFile = (e: any) => {
setFileData(e.target.files[0]);
};
const uploadFile = (e: any) => {
e.preventDefault();
const data = new FormData();
data.append("file", fileData);
axios({
method: "POST",
url: "http://localhost:5000/api/setImage",
data: data,
headers: {
"content-type": "multipart/form-data", // do not forget this
},
}).then((res) => {
alert(res.data.message);
});
};
server endpoint
router.post("/setImage", userController.setImage);
async setImage(req, res, next) {
try {
let uploadFile = req.body;
console.log(uploadFile);
} catch (e) {
next(e);
}
}
console.log shows empty object but I'm waiting img data
Try using multer with fs and tempy.
router.post("/setImage", multer({ dest: tempy.file() }).single("file"), async (req, res, next) => {
if (!req.file) return
fs.readFile(req.file.path, function (err, filedata) {
if (!req.file) return
// Here you should get your expected data in filedata variable
})
})

Response is not being sent back when using redis client

Why is no response being sent back in any of the cases (cache hit or miss)? I dont get any error either.
I'm trying to set up a simple redis based project.
import express from "express";
import axios from "axios";
let app = express();
import logger from "morgan";
import { createClient } from "redis";
const client = createClient();
await client.connect();
app.use(express.json());
app.use(logger("dev"));
app.get("/photos", async function (req, res) {
await client.get("photos", async (err, photos) => {
if (err) return next(err);
if (photos !== null) return res.json(JSON.parse(photos));
const { data } = await axios.get(
"https://jsonplaceholder.typicode.com/photos"
);
await client.setEx("photos", JSON.stringify(data));
res.json(data);
});
});
The issue is that you are mixing callback functionality with the newer async/await logic. According to the npm-redis docs the way to access a keys value is with await client.get()
app.get("/photos", async function (req, res) {
const photos = await client.get("photos");
if (photos) {
res.json(JSON.parse(photos))
} else {
try {
const { data } = await axios.get(
"https://jsonplaceholder.typicode.com/photos"
);
await client.setEx("photos", JSON.stringify(data));
res.json(data);
} catch(error) {
console.error(error)
res.json({data: error})
}
}
});
I have also added a try/catch block around the call to axios.get to try and capture any error that comes from the call and return that error in the response

Simple Fetch API Post Request Fails No Matter What

I have been working on this issue for 2 days, looked at various pages and cannot find a single solution that would work.
Please only reply if you know how to write them with async await functions and please reply if you know the answer of fetch api. I am not looking for axios solutions for the time being.
I have a backend server which runs on port 8000 of localhost, frontend runs on port 3000. Front end is written in React, backend is written in Node/Express.
I am able to successfully make a GET request from backend server but the POST request fails for some reason with the error "VM942:1 POST http://localhost:8000/frontend-to-backend 500 (Internal Server Error)"
Backend server has this error: SyntaxError: Unexpected token u in JSON at position 0
at JSON.parse ()
// React-To-Node-Connection
// React "App.js" file
// "package.json" file contains this
// "proxy": "http://localhost:8000"
useEffect(() => {
const getBackend = async () => {
const res = await fetch('backend-to-frontend');
const data = await res.json();
if (!res.ok) {
throw new Error(`Cannot get data from backend server. HTTP Status: ${res.status}`);
}
console.log(data.message);
// Prints "Hi from backend!"
}
getBackend();
const postBackend = async () => {
try {
const res = await fetch('http://localhost:8000/frontend-to-backend',
{
method: 'POST',
mode: 'no-cors',
body: JSON.stringify({ message: 'Hi from frontend!' }),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}
);
if (res.ok) {
const data = await res.json();
console.log(data);
}
} catch (error) {
console.error(error);
}
}
postBackend();
}, []);
Now the backend code:
app.get('/backend-to-frontend', (req, res) => {
res.json({ message: 'Hi from backend!' });
});
app.post('/frontend-to-backend', (req, res) => {
try {
const reactMessage = JSON.parse(req.body.data);
console.log(`message: ${reactMessage}`);
} catch (err) {
console.error(err);
}
});
How to fix this? Please help!
Full backend server code can be found here:
const express = require("express");
const app = express();
app.use(express.urlencoded({ extended: true }));
app.get('/backend-to-frontend', (req, res) => {
res.json({ message: 'Hi from backend!' });
});
app.post('/frontend-to-backend', (req, res) => {
try {
const reactMessage = JSON.parse(req.body.data);
console.log(`message: ${reactMessage}`);
} catch (err) {
console.error(err);
}
});
const port = process.env.PORT || 8000;
app.listen(port, function () {
console.log(`Backend server started on port ${port}.`);
});
with no-cors, you can only use simple headers, so you cannot POST JSON (see: Supplying request options)
Try urlencoded:
const postBackend = async() => {
try {
const res = await fetch('http://localhost:8000/frontend-to-backend', {
method: 'POST',
mode: 'no-cors',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
'message': 'Hi from frontend!'
})
});
if (res.ok) {
const data = await res.json();
console.log(data);
}
} catch (error) {
console.error(error);
}
}
postBackend();
and on the server, don't parse req.body, as it's already done by middleware:
app.post('/frontend-to-backend', (req, res) => {
console.log('req.body: ', req.body);
try {
const reactMessage = req.body.message;
req.body.data may be an object (check with debugger). If so, you might try to stringify before parsing :
JSON.parse(JSON.stringify(req.body.data))
I finally found the answer, here is my sample code. I did not change the React code that much so it is pretty much same, I removed the no cors section and added cors to Express JS code.
Here is my React code.
// React-To-Node-Connection
// "package.json" file has the following line
// "proxy": "http://localhost:8000"
// React Code
useEffect(() => {
const getBackend = async () => {
const res = await fetch('/backend-to-frontend');
const data = await res.json();
if (!res.ok) {
throw new Error(`Cannot get data from backend server. HTTP Status: ${res.status}`);
}
console.log(data.message);
}
getBackend();
const postBackend = async () => {
try {
await fetch('http://localhost:8000/frontend-to-backend',
{
method: 'POST',
body: JSON.stringify({ message: 'Hi from frontend!' }),
headers: {
'Content-Type': 'application/json'
}
}
);
} catch (err) {
console.error(err);
}
}
postBackend();
}, []);
And here is my Express JS code.
const express = require("express");
const app = express();
app.use(express.urlencoded({ extended: true }));
// Express JS Code
const cors = require('cors');
app.use(express.json());
app.use(cors());
app.get('/backend-to-frontend', (req, res) => {
res.json({ message: 'Hi from backend!' });
});
app.post('/frontend-to-backend', (req, res) => {
try {
console.log(req.body.message);
} catch (err) {
console.error(err);
}
});
const port = process.env.PORT || 8000;
app.listen(port, function () {
console.log(`Backend server started on port ${port}.`);
});
Thanks.

Fetch API not giving response data in Node.js

I have been trying to fix this but it gives me this: ReferenceError: json is not defined
this is my code:
const fetch = require('node-fetch');
function makeAFile(text){
fetch("http://bin.shortbin.eu:8080/documents", {
method: "post",
body: 'hey wassup'
})
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.log(err))
return json
}
console.log(makeAFile('nope'))
You need to understand, how async call works.
const fetch = require('node-fetch');
function makeAFile(text){
fetch("http://bin.shortbin.eu:8080/documents", { // this is async call
method: "post", // might give result later in time
body: 'hey wassup'
})
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.log(err))
return json // JSON is not defined and will be return just after 'Fetch' is called which is 'undefined'
console.log(makeAFile('nope'));
To make your code sync, you should use async await like this:
const fetch = require('node-fetch');
async function makeAFile(text){
let res = await fetch("http://bin.shortbin.eu:8080/documents", { // await helps you to wait here to make your code sync
method: "post",
body: 'hey wassup'
})
const json = res.json()
return json ;
}
try {
const response = await makeAFile('nope')); //use try catch to catch error
console.log(response);
}
catch (error) {
console.log(`Error ${error}`);
}
You seem to be confused with how to return data from an async call. You do that using callbacks like this:
const fetch = require('node-fetch');
function makeAFile(text){
return fetch("http://bin.shortbin.eu:8080/documents", {
method: "post",
body: text
})
.then(res => res.json())
.catch(err => { console.error(err) })
}
makeAFile('nope').then((result) => console.log(result));
You can read more about it here;
EDIT: Provide a solution using async/await
async function makeAFile (text) {
try {
const res = await fetch("http://bin.shortbin.eu:8080/documents", {
method: "post",
body: text
})
return res.json();
} catch (err) {
console.error(err);
}
}
// Define an anonymous async function to allow await statements inside
(async () => {
// this "await" here is important
const result = await makeAFile('nope');
console.log(result);
// now result is store inside of "result"
})();
You don't have access to json outside then callback. Just make your function async, that way you will have an access to it and outer context code can wait till your function will be resolved or rejected:
const fetch = require('node-fetch');
async function makeAFile(text){
const res = await fetch("http://bin.shortbin.eu:8080/documents", {
method: "post",
body: 'hey wassup'
})
const json = res.json()
console.log(json)
return json
}
and call it like:
try {
const result = await makeAFile('nope')
console.log(result)
} catch(err) {
console.log(err)
}
or
const result = makeAFile('nope').then(result => {
console.log(result)
})
.catch(err => {
console.log(err)
});
const fetch = require('node-fetch');
function makeAFile(text){
jsonOut = ''
fetch("http://bin.shortbin.eu:8080/documents", {
method: "post",
body: 'hey wassup'
})
.then(res => res.json())
.then(json => jsonOut = json)
.catch(err => console.log(err))
return jsonOut
}
console.log(makeAFile('nope'))
you cannot access value inside a promise. Just check this code

Set headers and body of a response in express

I want to create a node server that receives an URL and return the result of the request to that URL.
If I send him https://www.google.com in the request I need to receive the result back.
I want to receive the statusCode, the headers and the body.
I want to be able to receive HTML and JSON or any other type of response.
I was able to modify the statusCode but not the rest, any help would be great.
"use strict";
const fetch = require("node-fetch");
const express = require("express");
const app = express();
app.get("/", async (req, res) => {
const { fetch: requestUrl } = req.query;
if (requestUrl) {
try {
const proxyResponse = await fetch(requestUrl);
res.body = proxyResponse.body;
res.statusCode = proxyResponse.status;
res.send();
} catch (e) {
console.error(e);
res.sendStatus(500);
}
} else {
req.sendStatus(400);
}
});
app.listen(3000, () => {
console.log("listening");
});
I tried to modify the headers using res.set(proxyResponse.headers.raw());
but I get TypeError: Content-Type cannot be set to an Array
Thank you for your help.
const fetch = require("node-fetch");
const app = require("express")();
app.get("/", async (req, res) => {
const {fetch: requestUrl} = req.query;
if (requestUrl) {
try {
const proxyResponse = await fetch(requestUrl);
res.statusCode = proxyResponse.status;
// headers
//get
const headers = Array.from(proxyResponse.headers)
// Be careful about content-encoding header!
.filter(([key]) => !key.includes('content-encoding'))
.reduce((headers, [key, value]) => ({[key]: value, ...headers}), {});
//set
res.set(headers);
// body
//get
const body = await proxyResponse.text();
//set
res.send(body);
} catch (e) {
console.error(e);
res.sendStatus(500);
}
} else {
req.sendStatus(400);
}
});
app.listen(3000, () => console.log("listening"));

Resources