Post request with node js - javascript

I'm trying to make a post request with node.js and when I try to run it, I get the data to show up in the console but noot the body of my HTML. In the console I get the error
app.js:4 POST http://localhost:8000/addAnimal net::ERR_EMPTY_RESPONSE
postData # app.js:4
(anonymous) # app.js:25
app.js:21 Uncaught (in promise) TypeError: Failed to fetch
It seems like the function is working but not the actual post request part. I can't for the life of me figure out what I'm doing wrong.
This is my code:
server.js:
projectData = {};
/* Express to run server and routes */
const express = require('express');
/* Start up an instance of app */
const app = express();
/* Dependencies */
const bodyParser = require('body-parser')
/* Middleware*/
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
const cors = require('cors');
app.use(cors());
/* Initialize the main project folder*/
app.use(express.static('project1'));
const port = 8000;
/* Spin up the server*/
const server = app.listen(port, listening);
function listening(){
// console.log(server);
console.log(`running on localhost: ${port}`);
};
// GET route
app.get('/all', sendData);
function sendData (request, response) {
response.send(projectData);
};
// POST route
app.post('/add', callBack);
function callBack(req,res){
res.send('POST received');
}
// POST an animal
const data = [];
// TODO-Call Function
app.route('/addAnimal')
.get(function (req, res) {
res.sendFile('index.html', {root: 'project1'})
})
.post(function (req, res) {
data.push(req.body)
})
app.js
/* Function to POST data */
const postData = async ( url = '', data = {})=>{
console.log(data);
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
});
try {
const newData = await response.json()
// console.log(newData);
return newData.json()
}catch(error) {
console.log("error", error)
// appropriately handle the error
};
};
// TODO-Call Function
postData('/addAnimal', {animal:'lion'});
Any help would be greatly appreciated.
Thanks,
Mike

💡 The only one reason why you got message like it, it's because you never send response to the client.
👨‍🏫 So, You should to send response to the client. For an example, you can look at this code below: 👇
app.route('/addAnimal')
.get(function (req, res) {
res.sendFile('index.html', {root: 'project1'})
})
.post(function (req, res) {
data.push(req.body);
// send data to client
// you can change req.body with the object what you want to sent do the client
res.status(200).send(req.body);
})
📤 Update: Addtional information
Make sure you call the endpoint: http://localhost:8000/addAnimal.
Frontend: Make sure your code like this code below
const postData = async ( url = '', data = {})=>{
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
});
try {
console.log(await response.json());
return await response.json()
}catch(error) {
console.log("error", error);
};
};
I hope it can help you 🙏.

Try this:
app.route('/addAnimal')
.get(function (req, res) {
res.sendFile('index.html', {root: 'project1'})
})
.post(function (req, res) {
data.push(req.body);
res.send('done'); // send response
});

Change the app.js code with the below.
/* Function to POST data */
const postData = async (url = "", data = {}) => {
const response = await fetch(url, {
method: "POST", // *GET, POST, PUT, DELETE, etc.
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
try {
return response.json();
} catch (error) {
console.log("error", error);
// appropriately handle the error
}
};
// TODO-Call Function
(async function(){
let res = await postData("/addAnimal", { animal: "lion" });
console.log(res);
})();
And also change the post method like below.
app.route('/addAnimal')
.get(function (req, res) {
res.sendFile('index.html', {root: 'project1'})
})
.post(function (req, res) {
data.push(req.body);
res.status(200).send(data);
})

Related

I didn't get response from the nodejs server. It showing undefine after request to server

I hosted website on two different platforms like Firebase and Heroku
I Have some issues with that
Firstly, It showing cors errors when I post data from firebase hosted URL to the server which is hosted on Heroku
Then after resolving cors errors data couldn't from the server it showing undefined in console
Here is my server-side code which is hosted on Heroku
const express = require('express')
const path = require('path')
const PORT = process.env.PORT || 3000
const app = express()
const bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({extended:false}))
app.use(bodyParser.json())
app.use(express.json({limit:'1mb'}))
app.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', 'https://sample-377b8.web.app');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With,content-type,Accept,Authorization',);
res.header('Access-Control-Allow-Credentials', true);
if(req.method=="OPTIONS"){
res.header('Access-Control-Allow-Methods','PUT,POST,DELETE,PATCH')
return res.status(200).json({})
}
// Pass to next layer of middleware
next();
});
let data;
app.get('/',(req,res)=>{
res.send("hello world")
})
app.post('/',(req,res)=>{
data = req.body
console.log(data)
res.status(200).json({
"success":"200 response",
"res":"You are now just talked with server"
})
})
app.listen(PORT, () => console.log(`Listening on ${ PORT }`))
This is my client side code
document.getElementById('send').addEventListener('click',async()=>{
let data = {lat,lon}
await fetch('https://demoserver-app.herokuapp.com/',{mode:"no-cors"},{
method: 'POST', // or 'PUT'
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
}).then( async (dat) =>{
console.log(res.json())
}).then(res =>{
console.log(res)
})
})
It is giving the error on a console like
console error image
Headers information in the network tab
Header information of request image
I hope I can help you,
one issue that I see that can make this kind of output
is that you console.log(res) but .then referring to (dat)
And I don''t think you need async inside .then(it's already async function)
try this:
document.getElementById('send').addEventListener('click',async()=>{
let data = {lat,lon}
await fetch('https://demoserver-app.herokuapp.com/',{mode:"no-cors"},{
method: 'POST', // or 'PUT'
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
}).then( data =>{
data.json()
}).then(res =>{
console.log(res)
})
})
ok, so for the server side:
1)you need to destructure data from req.body, what you made is just adjust req.body to data bar.(see my solution)
2) for the post method you need to make a directory and not try it in the root directory.
try this code you will see the response you want
server:
app.post('/getmessage', (req,res) => {
const {data} = req.body;
console.log(data);
res.status(200).json({
"success":"200 response",
"res":"You are now just talked with server"
})
})
client:
fetch('http://localhost:3000/getmessage', {
method : 'post',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
data:"this is massage from client"
})
})
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.log(err))

Express js request body is not excatcly i want

Im working on simple app that allows you to register new user. I managed to create fetch POST request and catch it with express app.post method. It works but the value that req.body is retruning is not plain object but something more that I want.
It's literally returning something like this : { '{"login":"fff","password":"sss"}': '' }
But I want it to be just sth like this: {"login":"fff","password":"sss"}
Here is my client side code
function eventListener() {
const formSubmit = document.querySelector('.register-form');
const newUser = new Register();
formSubmit.addEventListener('submit', (e) => {
e.preventDefault();
newUser.checkInputs();
const form = e.target;
const formData = new FormData(form)
const userData = {
login: formData.get('login'),
password: formData.get('password'),
}
console.log(userData);
fetch('/register', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: JSON.stringify(userData)
})
.then(response => {
console.log(response);
})
})
}
document.addEventListener('DOMContentLoaded', eventListener)
And here is server code
const express = require('express');
const path = require('path');
const app = express();
app.use(express.json())
app.use(express.urlencoded({
extended: true
}))
app.use(express.static('static'))
app.post('/register', (req, res) => {
console.log('ok');
console.log(req.body);
res.end();
})
app.listen(process.env.PORT || 5000, () => {
console.log('running...');
})
Don't lie to the server:
'Content-Type': 'application/x-www-form-urlencoded'
You are sending JSON.
By telling the server you are NOT sending JSON, you are confusing it.
It is trying to parse it as application/x-www-form-urlencoded
Tell it you are sending JSON:
'Content-Type': 'application/json'

React, axios, content-type

I have already searched a lot, but none of the solutions found work: Cannot send content-type by axios. but if I use the postman interceptor and I 'send' the request generated by axios this time it works: the node.js / express server correctly receives the request and body-parser works normally!
React side:
const API_URL = "http://localhost:8800/auth/";
const headers = {
accept: 'application/json, text/plain, */*',
'content-type': 'application/json;charset=UTF-8'
};
class AuthService {
register(pseudo, email, password) {
return axios.post(API_URL + "signup/",
{ pseudo, email, password },
{ headers: headers})
.then(response => {
if (response.data.accessToken) {
localStorage.setItem("user", JSON.stringify(response.data));
}
return response.data;
});
}
server side
const app = express();
app.use(function (req, res, next) {
console.log( req.headers);
next();
});
app.use( bodyParser.urlencoded({ extended: true }), bodyParser.json());
Usually when I use axios I send the headers in a config variable like this and I stringify the body so it sends as JSON object and not a JS object.
const config = {
headers: {
'Content-Type': 'application/json',
},
};
const body = JSON.stringify({arguments});
try {
const res = await axios.post(/url, body, config);
...
Here's a link to the docs for a little more reading about it:
https://github.com/axios/axios

node.js fetch post request returning index.html instead of json

I have a node.js app connected to a dialogflow bot I created, in which there's only one file: app.js.
I have index.html, index.js UI for the bot, which when I open unconnected to app.js, runs perfectly. I get json response from app.js
However, when I tried to include the UI (index.html and index.js) in app.js, the post method is returning index.html instead of the json it returned before, resulting in error: "SyntaxError: Unexpected token < in JSON at position 0" (because index.html is returned instead of json)
Here's my app.js
const dialogflow = require('#google-cloud/dialogflow');
const uuid = require('uuid');
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const port = 9000;
const sessionId = uuid.v4();
app.use(bodyParser.urlencoded({
extended: false
}));
// ------------------The following code is the one I use for including the UI----------------------------------
const path = require('path');
app.use(express.static('botui'));
app.use('/', function(req,res){
res.sendFile(path.join(__dirname+'/botui/index.html'));
});
// ------------------------------Code for including the UI ended-----------------------------------------------
// ------------------When I did not use the above code and just opened file://index.html it worked great-------
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
app.post('/send-msg',(req,res)=>{
runSample(req.body.MSG).then(data=>{
res.send({
statusCode: 200,
body: {},
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
Reply:data})
})
})
/**
* Send a query to the dialogflow agent, and return the query result.
* #param {string} projectId The project to be used
*/
async function runSample(msg, projectId = 'bot_ID') {
// Create a new session
const sessionClient = new dialogflow.SessionsClient({
keyFilename:"BOT-KEY.json"
});
const sessionPath = sessionClient.projectAgentSessionPath(projectId, sessionId);
// The text query request.
const request = {
session: sessionPath,
queryInput: {
text: {
// The query to send to the dialogflow agent
text: msg,
// The language used by the client (en-US)
languageCode: 'en-US',
},
},
};
// Send request and log result
const responses = await sessionClient.detectIntent(request);
console.log('Detected intent');
const result = responses[0].queryResult;
console.log(` Query: ${result.queryText}`);
console.log(` Response: ${result.fulfillmentText}`);
if (result.intent) {
console.log(` Intent: ${result.intent.displayName}`);
} else {
console.log(` No intent matched.`);
}
return result.fulfillmentText;
}
app.listen(port,()=>{
console.log("Running on port: " + port)
})
And here's the code from index.js which sends the POST request:
fetch(url, {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
method: 'POST',
body:data
})
.then(res => res.json())
.then(response => {
console.log(response);
serverMessage(response.Reply);
})
.catch(error => console.error('Error h:', error));
It seems you should replace app.use('/', function(req,res){ to app.get('/', function(req,res){
take a look at Difference between app.use and app.get in express.js

Express routes giving 500 internal server

my server can't find the api's that i created in api directory. it leads to 500 internal server.
I have checked routes.js but i see that everything is right. i have an error.js file for file handling. Here's my code.
'use strict';
let router = require('express').Router();
// Middleware
let middleware = require('./controllers/middleware');
router.use(middleware.doSomethingInteresting);
// Tasks
let tasks = require('./controllers/tasks');
let createkeypairs = require('./controllers/createkeypairs');
let importaddress = require('./controllers/importaddress');
let getwalletinfo = require('./controllers/getwalletinfo');
router.get('/tasks', tasks.findAll2);
router.get('/createkeypairs', createkeypairs.findAll);
router.get('/importaddress', importaddress.findAll);
router.get('/getwalletinfo', getwalletinfo.findAll);
router.post('/buggyroute', tasks.buggyRoute);
// Error Handling
let errors = require('./controllers/errors');
router.use(errors.errorHandler);
// Request was not picked up by a route, send 404
router.use(errors.nullRoute);
// Export the router
module.exports = router;
now showing you my createkeypairs.js
'use strict';
let errors = require('./errors.js');
var request = require("request");
var options = { method: 'POST',
url: '127.0.0.1:18332',
headers:
{ 'Authorization': 'Basic bXVsdGljaGFpbnJwYzpHTmJ5enJhMnlHRjN4Ymp1cnluRTFucTlnV1ExRXV3OTFpYVBqSkt5TkJxdA==',
'cache-control': 'no-cache',
'Cache-Control': 'no-cache',
'Content-Type': 'application/json' },
body: { method: 'createkeypairs', params: [], chain_name: 'tokenchain' },
json: true };
exports.findAll = (req, res, next) => {
// Simulate task list, normally this would be retrieved from a database
let createkeypairs ;
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log("working here ");
// res.json(body);
});
};
exports.buggyRoute = (req, res, next) => {
// Simulate a custom error
next(errors.newHttpError(400, 'bad request'));
};
I think the problem is in createkeypair file.
Try this code once for your createkeypairs.js:
'use strict';
let errors = require('./errors.js');
var request = require("request");
let config = require('config');
var auth = 'Basic ' + Buffer.from(config.user + ':' + config.pass).toString('base64');
var url = config.url;
var chain = config.chain;
var options = { method: 'POST',
url: url,
headers:
{ 'cache-control': 'no-cache',
Authorization : auth,
'Content-Type': 'application/json' },
body: { method: 'importaddress', params: ["address"], chain_name: chain },
json: true };
exports.findAll = (req, res, next) => {
// Simulate task list, normally this would be retrieved from a database
let createkeypairs ;
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
res.json(body);
});
};
exports.buggyRoute = (req, res, next) => {
// Simulate a custom error
next(errors.newHttpError(400, 'bad request'));
};
Do tell me if it works or not.

Categories

Resources