Why is data not received by Node.js through POST request? - javascript

So I have this functionality.
The client is sending data through jquery post function
$.post(currentURL + "/api/tables", newReservation,
function(data) {
if (data == true) {
alert("Yay! You are officially booked!")
}
if (data == false) {
alert("Sorry you are on the waitlist")
}
$('#reserve_name').val("");
$('#reserve_phone').val("");
$('#reserve_email').val("");
$('#reserve_uniqueID').val("");
});
Then Node.js is receiving it here
app.post("reserve/api/tables", function(req, res) {
var newentry = req.body;
console.log(newentry);
entries.push(newentry);
res.json(newentry);
});
However, console.log is giving me this error
jquery.js:9631 POST http://localhost:8080/api/tables 404 (Not Found)

Because you are doing the request to the url: http://localhost:8080/api/tables , but your server is waiting you at : "reserve/api/tables".
Try to target: http://localhost:8080/reserve/api/tables

your routing specifies a localhost:8080/reserve/api/tables,
remove the 'reserve' routing

You are missing leading slash in
app.post("reserve/api/tables", function(req, res) {
so it should be
app.post("/reserve/api/tables", function(req, res) {
or
app.post("/api/tables", function(req, res) {
as edited later

Related

Nodejs: Display POST data from another website

Im trying to figure it out for past 6 hours, but Im out of ideas..
What Im trying to accomplish:
I want to display a JSON data that looks like this
movie {title: " xxxxx", seed: "number", url: "zzzzzzzzz"}
I want to display it on my Node server(via jade), but what I accomplished till now is to send it from the website to my node server via POST request using this code:
My JS script
var http = new XMLHttpRequest();
var url = "http://localhost:8080/";
var params = arr; <------ My JSON data
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
console.log(http.responseText);
}
}
http.send(params);
After using above code in my google chrome developer tools on the website I actually have that data, I receive the JSON array in my node, here is my node code:
My app.js node server
const http = require("http");
const express = require('express');
const app = express();
const myParser = require('body-parser');
app.set('views', __dirname + '/views')
app.set('view engine', 'jade')
app.use(express.static(__dirname + '/public'))
app.use(myParser.urlencoded({ extended: false }));
app.use(myParser.json())
var allowCrossDomain = function (req, res, next) {
res.header('Access-Control-Allow-Origin', "*");
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
app.use(allowCrossDomain);
app.get('/', function (req, res, next) {
res.render('index');
})
app.get('/tl', function (req, res, next) {
res.render('tl');
})
app.post("/", function (req, res) {
response = {
first_name: req.body
};
console.log('SHOW ME BODY')
console.log(req.body);
res.send('You sent: this to Express');
});
app.listen(8080);
And this is what Im receiving in my node command prompt:
{ '[{"title":" SOME-MOVE-TITLE","seed":"NUMBER","url":"https://SOMEURLS.COM', etc. etc. etc.
And finally here is my layout.jade file
doctype
html
head
title Bolo Node Server
link(rel="stylesheet", type="text/css", href="stylesheet/style.css")
body
header
h1 My Site
block content
footer
p Running on node with Express, Jade and Stylus
And index.jade
extend layout
block content
p= 'Block content works'
script.
if req.body != undefined
div(id='data')= req.body
I really run out of ideas on how to display the json array Im receiving...help me out please
Update
My index.jade
extend layout
block content
p= 'Block content works'
div(id='data')
pre
test= jsonString
My app.js looks now like this:
app.get('/', function (req, res, next) {
res.render('index');
})
app.post("/", function (req, res) {
// Get string representation
var jsonString = JSON.stringify(req.body || {}); // use JSON.stringify(req.body || {}, null, 2) for formatted JSON
console.log(jsonString);
res.render('index', {test: jsonString});
//res.send('You sent: this to Express');
});
I see the data in my node command prompt, but I dont see it on my local website http://localhost:8080/ the div(id='data') is showing me empty.. nothing, how do I get the jsonString there?? I want it to show me the data on my local website..
**
UPDATE
**
I ended up just putting the data into the sqlite3 database and then retrieving the data via GET request and finally putting it into my jade template. I thought I can go around and not use sqlite3 but I couldnt figure out how.
When you say that you want to display the json, if you just want to see the contents of the json you can use res.json.
app.post("/", function (req, res) {
// Send back the request body if present or else, an empty object
res.json(req.body || {});
});
If you want it to be displayed inside a template, you can get a string representation of the json using JSON.stringify(req.body) and render that in your template by passing it to it as a local variable.
app.post("/", function (req, res) {
// Get string representation
var jsonString = JSON.stringify(req.body || {}); // use JSON.stringify(req.body || {}, null, 2) for formatted JSON
res.render('jsonView',{jsonString});
});
And in your template:
div(id='data')
pre
code = jsonString
You should pass the data in the template.
res.render('index', {data: 'data'});
And show it with:
data = data
p #{data}
First you should parse your incoming data, as is application/x-www-form-urlencoded. You'll need to JSON.parse req.body first and encode your response as json too
app.post("/", function (req, res) {
var response = try { JSON.parse(req.body) } catch(e) { console.error('Invalid Data') };
res.json(response || {});
});
You could also send your data as 'application/json' from you client JS and save receive a JSON directly to the req.body.
Hope it helps
UPDATE (if you want to append new data via async requests on the client)
In this post you can see the use of XmlHttpRequest with jquery $.ajax() which is basically the same concept of async requests after the DOM is rendered on your server.
Imagine the step 3 being your Jade rendered HTML
I ended up just putting the data into the sqlite3 database and then retrieving the data via GET request and finally putting it into my jade template. I thought I can go around and not use sqlite3 but I couldnt figure out how.
Here is the code
app.post("/", function (req, res) {
var jsonString = JSON.stringify(req.body || {});
db.serialize(function () {
var stmt = db.prepare("INSERT INTO movies (id, title, seed, url) VALUES (?,?,?,?)");
for (var i = 0; i < req.body.length; i++) {
var d = new Date();
var data = req.body;
var n = d.toLocaleTimeString();
stmt.run(i, req.body[i].title, req.body[i].seed, req.body[i].url);
}
stmt.finalize();
});
res.send('You sent: this to Express');
});
Retrieving the data from the database
app.get('/tl', function (req, res, next) {
db.all('select * from movies', function (err, rows) {
if (err)
return next(err);
var dataO = [];
rows.forEach(function (row) {
dataO.push(row);
})
res.render('tl', { dataO: dataO });
})
})

Making multiple AngularJS Post requests to an Express Server? Server crashes on second post request

So given that I can't run these two post requests at the same time in my client, I'm trying to run the second post in the .then section of the first post. Which has always worked fine on my other projects. But for some reason when the second post request fires my server doesn't reply. When I check the console of the server, I notice it crashed and there's an error message (at the bottom of this post).
What could be causing this???
I have put breakpoints on the second post request in my server's code, and noticed the breakpoints don't even get hit. The server crashes before hitting and giving me the option to continue.
Client Code (gets fired when user presses a button):
$scope.searchCharacter = function(){
var request = {name: $scope.charName, realm: $scope.selectedRealm};
//First post request
$http.post('/searchCharacter', request)
.then(function(response) {
//sets some variables
var id = 0;
//Second post request
$http.post('/helloworld', id)
.then(function(response) {
//sets some more variables
debugger;
});
});
}
Server Code:
//First post request
app.post('/searchCharacter', jsonParser, function (req, res) {
blizzard.wow.character(['profile', 'stats', 'items', 'statistics'], { origin: 'us', realm: req.body.realm.name, name: req.body.name })
.then(response => {
if(response.status != 200){
res.send("That character doesn't exist! Please enter a valid character name.");
} else {
console.log(response.data);
res.send(response.data);
}
});
});
//Second Post Request
app.post('/helloworld', jsonParser, function (req, res) {
console.log(req.body);
res.send("hello");
});
Error message:
SyntaxError: Unexpected token #
at Object.parse (native)
at createStrictSyntaxError
(c:\Users\RDubz\Documents\Interviews\EagleDream
12-7-17\Project\node_modules\body-parser\lib\types\json.js:157:10)
at parse (c:\Users\RDubz\Documents\Interviews\EagleDream
12-7-17\Project\node_modules\body-parser\lib\types\json.js:83:15)
at c:\Users\RDubz\Documents\Interviews\EagleDream
12-7-17\Project\node_modules\body-parser\lib\read.js:121:18
at invokeCallback (c:\Users\RDubz\Documents\Interviews\EagleDream
12-7-17\Project\node_modules\body-parser\node_modules\raw-body\index.js:224:16)
at done (c:\Users\RDubz\Documents\Interviews\EagleDream
12-7-17\Project\node_modules\body-parser\node_modules\raw-body\index.js:213:7)
at IncomingMessage.onEnd
(c:\Users\RDubz\Documents\Interviews\EagleDream
12-7-17\Project\node_modules\body-parser\node_modules\raw-body\index.js:273:7)
at emitNone (events.js:67:13)
at IncomingMessage.emit (events.js:166:7)
at endReadableNT (_stream_readable.js:921:12)
Try this:
$scope.searchCharacter = function(){
var request = {name: $scope.charName, realm: $scope.selectedRealm};
//First post request
$http.post('/searchCharacter', request)
.then(function(response) {
//sets some variables
var id = 0;
//Second post request (append id to route).
$http.post('/helloworld/' + id)
.then(function(response) {
//sets some more variables
debugger;
});
});
}
//First post request
app.post('/searchCharacter', jsonParser, function (req, res) {
blizzard.wow.character(['profile', 'stats', 'items', 'statistics'], { origin: 'us', realm: req.body.realm.name, name: req.body.name })
.then(response => {
if(response.status != 200){
res.send("That character doesn't exist! Please enter a valid character name.");
} else {
console.log(response.data);
res.send(response.data);
}
});
});
//Second Post Request (get id from req.params.id)
app.post('/helloworld/:id', function (req, res) {
console.log(req.params.id);
res.send("hello");
});
It appends id to the helloworld request, and defines a route helloworld/:id using req.params.id to pull the id out of the request.
Facepalm I was using var id = 0 and passing it to my function without realizing it needed to be passed as either an object or a param. Thanks to those who commented!

URIError: Failed to decode param '/December%2015,%' in framework express

Using express framework I did a middleware that handles a URI with a date as parameter.
app.get("/:date",function(req,res){
var result;
var myDate=req.params.date
if(moment(myDate).isValid()){
//some code here
}
else {
//some code here
}
}
and the http is for example:
https://theweb.com/December%2015,%2020
The middleware works well. But if the http finish in % as in
https://theweb.com/December%2015,%
it gives a error:
URIError: Failed to decode param '/December%2015,%'
and what I would like is to convert that error in the display of a message as Bad Request.
You can register an error handler like this:
app.use(function(err, req, res, next) {
console.log('hit error handler');
res.sendStatus(err.status || 500);
});
Note that the function must have 4 arguments, even if you don't use all of them. This function can then respond in whatever way you think is appropriate, in my example I've just sent back the status code. Express sets err.status to 400 for a URIError.
See https://expressjs.com/en/guide/error-handling.html
I had already use this middleware, but no result. It still gives same error when the URI is: https://myweb.com/December%2015,%
URIError: Failed to decode param '/December%2015,%'
Might be is the position of the code
var express = require('express');
var moment=require("moment")
var app = express();
app.use(express.static('public'));
app.use(function(err, req, res, next) {
console.log('hit error handler');
res.sendStatus(err.status || 500);
});
app.get("/", function (request, response,next) {
response.sendFile(__dirname + '/views/index.html');
});
app.get("/:date",function(req,res){
var result;
var myDate=req.params.date //From here comes the error
if(moment.unix(myDate).isValid()){
// some code
result={/*some code*/}
} else if(moment(myDate).isValid()){
//some code
result={/*some code*/}
else {
result={/*some code*/}
}
res.json(result)
})

Before filter for all post requests in node.js

I have the below code in my node.js app.js:
var express = require('express')
,cors = require('cors')
,app=express();
var users = require('./routes/users');
//some other codes
.....
app.use('/', routes);
app.use('/users', users );
If a request is made to /users/adduser, it will go to the users.js in the routes folder.
Now I want to add a filter which will capture all the POST requests and do some validations and only if the conditions are satisfied the POST should go to its handler.
I.e if i get a /users/adduser with a POST request, before going to the method in the users.js in the routes folder, I should be able to capture that request and stop it if the condition is not met.
UPDATE 1
Now i am having this app.use function, but in the result i am getting undefined as its not waiting till the function is returning value
app.use(function (req, res, next) {
req.db = db;
if (req.method != "POST") {
next();
}
else {
var userData = req.body;
var result = Check(userData);
if(result){
next();
}
}
});
function Check(userdata) {
var url = "someurl"+userdata.Id;
var request = require("request");
request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
if (response.toJSON().body.id == userId) {
return true;
// i also tried next();
}
}
})
};
You can write a simple middleware function for that:
var validator = function(req, res, next) {
// If the request wasn't a POST request, pass along to the next handler immediately.
if (req.method !== 'POST') return next();
// Perform your validations.
Check(req.body, function(err) {
// Validation failed, or an error occurred during the external request.
if (err) return res.sendStatus(400);
// Validation passed.
return next();
});
};
function Check(userdata, callback) {
var url = "someurl"+userdata.Id;
var request = require("request");
request({ url: url, json: true }, function(error, response, body) {
if (!error && response.statusCode === 200) {
if (response.toJSON().body.id === userId) {
return callback(null, true);
}
}
return callback(new Error());
})
};
You have various points at which you can insert this middleware, which kind of depend on how exactly your app is structured.
One option:
app.use('/users', validator, users);
Or, if you have a separate router for /users (in ./routes/users.js):
router.use(validator);
Or, if you have a separate POST route for /users/adduser:
router.post('/adduser', validator, function(req, res) { ... });
In the last case you don't have to check req.method in the validator middleware because it's limited to the POST handler anyway.
You can use a route middleware assuming you use Express.
If you want to perform validations for all POST requests to /users then you can add the following middleware before the route handler:
router.use(function (req, res, next) {
if (your request is valid){
next();
} else {
//Return a response immediately
res.status(400).json({ message: "Bad request" });
}
});
Check(userdata) running asycn so you should use callback here :D
function Check(userdata,cb) {
var url = "someurl"+userdata.Id;
var request = require("request");
request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
if (response.toJSON().body.id == userId) {
cb(null,true);
}
}
})
};
Then change the middleware like
var result = Check(userData,function(err,result){
if(result){
next();
}
}

Client receive json object to javascript

I want my server to send a JSON object to a javascript on the client's side. How can the client get the object into his javascript and not show the object on screen?
In my server :
app.get('/', function (req, res) {
res.send(jsonObj);
});
Thank you!
Using jquery i will show you a quick example of how things work:
Client
$.get('youserver.com/', {mydata: 'content'}, function(response){
//callback triggered when server responds
console.log(JSON.stringify(response));
});
Server
app.get('/', function (req, res) {
if(req.params.mydata === 'content'){
res.end("you sent content");
} else {
res.end("you sent something else");
}
});
Do you understand what i mean?
Try to use res.json() method
app.get('/', function (req, res) {
res.json(jsonObj);
});

Categories

Resources