node js error on response methods between server and client - javascript

Hey im currently working on my first real webpage using node.js
Im using Express, ejs for layout and redis as database. Im trying to send an ajax call from my index page through my client to my server, use the ajax-call there and pass the final json back to my client where i try to render it on the next ejs page.
Ajax:
$(function(){
$(".search").click(function() {
$.ajax({
method: "POST",
url: "/search",
cache: false,
data: {ort: "hierundda", activity: "Wandern", datum: "01.09.2015"},
dataType: "json",
success: function(data){
alert('Success!')
}
, error: function(jqXHR, textStatus, err){
alert('text status '+textStatus+', err '+err)
}
});
});
});
My server route:
rest.post("/search", jsonParser, function(req, res){
/*some database action with redis */
res.json(dataJson);
});
});
My client route:
app.post('/search', jsonParser, function(req,res){
var test = JSON.stringify(req.body);
fs.readFile('./filterergebnis.ejs', {encoding: 'utf-8'}, function(err, filestring){
if(err){
throw err;
}
else{
var options = {
host: 'localhost',
port: 3000,
path: '/search',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': test.length
}
}
var req = http.request(options, function(res) {
res.on('data', function (chunk) {
var userdata = JSON.parse(chunk);
console.log(userdata);
var html = ejs.render(filestring, userdata);
//here does the error appear...
res.setHeader('content-type', 'text/html');
res.writeHead(200);
res.write(html);
res.end();
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.write(test);
req.end();
}
});
});
This is what the error looks like:
http://www.pic-upload.de/view-28225954/stack.png.html
index.ejs is running on default

You're using conflicting res variable names. Check the variable names of the callbacks from app.post() and http.request().
If you change to response instead, it might work, if there is no other problems:
var req = http.request(options, function(response) {
response.on('data', function (chunk) {
...

Related

How to POST JSON data to server using AJAX jQuery

Keep getting error when trying to post 'order' JSON data to JSON file on Node.js server
GET request works fine but 'Error' function executes instead of the 'success' function when trying to do a POST request. Am I missing anything? Do I need to use php?
The dev tools console shows the following error message:
POST http://.../orders.json 405 (Method Not Allowed) jquery.js:10109
$("#add-order").on("click", function()
{
var order =
{
name: $name.val(),
food: $food.val()
};
$.ajax(
{
type: "POST",
url: "orders.json",
dataType: "json",
contentType: "application/json",
data: JSON.stringify(order),
processData: false,
success: function(newOrder)
{
alert("success");
$orders.append("<li>Name: " + newOrder.name +", food: " + newOrder.food + "</li>");
},
error: function()
{
alert("Error posting order");
}
});
});
Node js server
const http = require("http");
const fs = require("fs");
const port = 3000;
const server = http.createServer(function(request, response)
{
response.writeHead(200, { "Conent-Type": "text/json" })
fs.readFile("orders.json", function(error, data)
{
if (error)
{
response.writeHead(404);
response.write("Error: File Not Found");
}
else response.write(data);
response.end();
})
});
server.listen(port, function(error)
{
if (error) console.log("Something went wrong. Error: ", error);
else console.log("server is listening to port " + port);
})
var http = require('http');
var requestListener = function(req, res) {
console.log("" + req.method)
if (req.method === "POST") {
let data = '';
req.on('data', chunk => {
data += chunk;
})
req.on('end', () => {
console.log(data)
res.end("received");
})
}
res.writeHead(200);
res.end('Hello, World!' + req.method);
}
var server = http.createServer(requestListener);
server.listen(3000, function() {
console.log("Listening on port 3000")
});
//curl -d '{"name":"1","age":"2"}' -H 'Content-Type: application/json' localhost:3000
//Output
/*
Listening on port 3000
POST
undefined
{"name":"1","age":"2"}
*/
Or you can explore express or any other middle ware for easy parsing and handling.

sending params through routes

I'm trying to pass some parameters through the URL, i tried to do it this way but it isn't working, the "get(\users:id)" is probably the mistake but i'm not sure whats the correct way:
$.ajax({
type: 'GET',
URL: "'../users/"+id+"'",
success: function(data) {
console.log("success");
}
})
and then i use this route:
app.get('/users/:id', function(req, res) {});
shouldn't this work?
Try this way:
$.ajax({
type: 'GET', URL: "'../users/"+id+"'",
success: function(data) {
console.log("success");
}
}):
An then the route should be:
app.get("/users/:id", function (req, res) {
var id = req.params.id;
});
Your problem seems to be attempting to hit a file system relative path from your client, and the fact that there is no response being sent from your endpoint. Try this (using fetch which is the newer way instead of $.ajax):
fetch('/users/' + id)
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
});
And in your server:
app.get('/users/:id', function(req, res) {
console.log(req.params); // this should be an object containing an `id` param
res.send({});
});

Node.js - jQuery. Get PDF from server and display on front-end

I'm bit stuck here. My intent is to first get all files (filenames) from a static folder + subfolders and list all on front-end.
When user clicks one of the filenames (mostly pdf's), the server returns the selected items content.
I'm able to send the pdf data as binary to front-end, but how could I display the data in a new tab with js/jQuery?
so far..
Server.js -
// Importing and initializing npm/node plugins
var app = require('express')();
var server = require('http').createServer(app);
var logger = require('morgan');
var bodyParser = require('body-parser');
var pdf = require('express-pdf');
var cors = require('cors');
var fs = require('fs');
// Import config settings
var config = require('./config.json');
app.use(logger('dev'));
// Allow application/x-www-form-urlencoded and application/json
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json({
limit: '50mb'
}));
app.use(cors());
app.use(pdf);
app.get('/getfiles', function (req, res) {
var dir = config.sourceDir;
var foundFiles = [];
fs.readdir(dir, function (err, files) {
if (err) {
console.log('Error reading ' + dir);
process.exit(1);
}
console.log('Listing files in Directory ' + dir);
files.forEach(function (f) {
foundFiles.push(f);
});
res.json(foundFiles);
});
});
app.post('/showfiles', function (req, res) {
var file = req.body.filename;
var dir = config.sourceDir;
fs.readFile(dir + file, function (err, data) {
res.contentType('application/pdf');
res.send(data);
});
});
// Open server in port
server.listen(config.port, function () {
console.log('Server listening on port: ' + config.port);
});
module.exports = app;
On front-end -
$(function () {
getFiles();
});
function getFiles() {
$.ajax({
type: "GET",
url: "http://localhost:3000/getfiles",
contentType: "application/json; charset=utf-8",
crossDomain: true,
dataType: "json",
success: function (data, status, jqXHR) {
if (data) {
$.each(data, function (index, value) {
$("#listContainer1").append("<li><a href='#' onclick='showFile(this)'>" + value + "</a></li>");
});
}
},
error: function (jqXHR, status) {
console.log("Error fetching data");
}
});
}
function showFile(file) {
$.ajax({
type: "POST",
data: JSON.stringify({
"filename": $(file).text()
}),
url: "http://localhost:3000/showfiles",
contentType: "application/json; charset=utf-8",
crossDomain: true,
dataType: "application/pdf",
success: function (data, status, jqXHR) {
if (data) {
var file = new Blob([data], {
type: 'application/pdf'
});
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
}
},
error: function (jqXHR, status) {
console.log("Error showing file");
}
});
}
But this keeps falling into the "Error showing file" pit. :(
EDIT:
The first error was corrected by removing the "application/pdf" from post, but now its opening an empty pdf with correct page limit
On the server, change the file fetch code to this:
app.get('/showfiles/:filename', function (req, res) {
var options = {
root: config.sourceDir
};
var fileName = req.params.filename;
res.sendFile(fileName, options, function (err) {
if (err) {
// Handle error
} else {
// Handle success
}
});
});
So I switched the method to GET and used the built-in sendFile method in Express. Then on the front end it's much easier. You can get rid of the showFile function and just update the getFiles function:
function getFiles() {
$.ajax({
type: "GET",
url: "http://localhost:3000/getfiles",
contentType: "application/json; charset=utf-8",
crossDomain: true,
dataType: "json",
success: function (data, status, jqXHR) {
if (data) {
$.each(data, function (index, value) {
$("#listContainer1").append('<li>' + value + '</li>');
});
}
},
error: function (jqXHR, status) {
console.log("Error fetching data");
}
});
}
Code has not been tested and most likely has mistakes, but should give you a gist of another way you can tackle the problem.

ExpressJS does not seem to work with ajax calls

I'm trying to figure out Node.js to use as an api to do GET, POST, etc. I've been stuck trying to figure out why this post is not working.
My ajax call:
$.ajax({
method: "POST",
contentType: 'application/json',
dataType: 'json',
url: "localhost:8000/login",
data: JSON.stringify({user:"john", pass:"123"}),
error: function () {
alert('error');
},
success: function (data) {
alert('success');
}
});
In my express:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/login', function (req, res) {
var user = req.body.user;
var password = req.body.pass;
if(user == 'john' && password == '123') {
res.status(200);
} else {
res.status(401);
}
});
app.listen(8000, function () {
console.log('Example app listening on port 8000!');
});
Any help is greatly appreciated.
you should return some response from your express code, also response should be ended especially in case of just sending only the status code like res.status(401);
app.post('/login', function (req, res) {
var user = req.body.user;
var password = req.body.pass;
if(user == 'john' && password == '123') {
res.status(200).json({t:1});
} else {
res.status(401);
}
res.end();
});
This work for me:
$.ajax({
type: "POST",
contentType: 'application/json',
dataType: 'json',
url: "/login",
data: JSON.stringify({user:"john", pass:"123"}),
error: function (err) {
console.log(err);
alert('error');
},
success: function (data) {
alert('success');
}
});
app.post('/login', function (req, res, next) {
var user = req.body.user;
var password = req.body.pass;
if(user == 'john' && password == '123') {
res.status(200).json({s: 1});
} else {
res.status(401).json({e: 2});
}
});
var json = JSON.stringify({user:"john", pass:"123"});
$.ajax({
dataType: 'json',
type: "POST",
url: "/login",
data: json
}).done(function(data){
console.log("works fine");
});
Should work for an Ajax post function, sending the data to the node server.
The url needs to match the url of the app.post in the node server file, you don't need localhost in front of it.
ContentType is also not necessary and I made the json object outside of the Ajax call instead of setting it inside the Ajax call.
var express = require('express');
var parser = require('body-parser');
var app = express();
var port = 8000;
app.use(parser.urlencoded({extended: false}));
app.use(parser.json());
app.use(express.static('public'));
app.post('/login', function (req, res) {
var user = req.body.user;
var password = req.body.pass;
if(user == "john" && password == "123") {
res.status(200);
} else {
res.status(401);
}
});
var server = app.listen(port, function () {
var host = server.address().address
var port = server.address().port
console.log("App listening at http://%s:%s", host, port);
});
And that should work for the node server itself.
I set the server running, so you can always keep track of what port it's listening on, so you don't need to bother scrolling down to change the port, just change the port at the top of your file.
Further the /login was looking fine to me.
Also, I edited the app.use statements and added an extra one.
I think you have to parse request to JSON.
your code is:-
$.ajax({
method: "POST",
contentType: 'application/json',
dataType: 'json',
url: "localhost:8000/login",
//here you used JSON.stringify and on server side you have to parse it to use 'user' and 'pass' as a key of json
data: JSON.stringify({user:"john", pass:"123"}),
error: function () {
alert('error');
},
success: function (data) {
alert('success');
}
});
on the server side
<br>
app.post('/login', function (req, res) {
//parse data to JSON for further use
var dataObj = JSON.parse(req.body.data);
if(dataObj.user == 'john' && dataObj.password == '123') {
res.status(200);
} else {
res.status(401);
}
});

Http get multiple json files from different API endpoints using node express

I'm looking into the most efficient way to get multiple JSON files from different API endpoints using node.
Basically i'd like to store each JSON object in a variable, and send them all to Jade template files for parsing.
I've got it setup working for getting one single JSON file (jsonFile1) by doing the following:
httpOptions = {
host: 'api.test123.com',
path : '/content/food/?api_key=1231241412',
headers: {
"Accept": "application/json",
'Content-Type': 'application/json'
},
method: "GET",
port: 80
}
var jsonFile1;
http.get(httpOptions, function(res) {
var body = '';
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
jsonFile1= JSON.parse(body)
console.log("Got response: " + jsonFile1);
});
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
app.set('views', __dirname);
app.get('/', function(req, res) {
res.render('home', {
data: jsonFile1
});
});
But i don't really want to have to repeat all of this to get multiple json endpoints and send them to home jade template.
Any ideas to do this efficiently?
Based on your code, this is a quick example using the excellent async library.
var async = require('async'),
// Array of apis
httpOptions = [
{
host: 'api.test123.com',
path : '/content/food/?api_key=1231241412',
headers: {
"Accept": "application/json",
'Content-Type': 'application/json'
},
method: "GET",
port: 80
},
host: 'api.test234.com',
path : '/content/food/?api_key=1231241412',
headers: {
"Accept": "application/json",
'Content-Type': 'application/json'
},
method: "GET",
port: 80
}
];
// Put the logic for fetching data in its own function
function getFile(options, done) {
http.get(options, function(res) {
var body = '';
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
done(null, JSON.parse(body));
console.log("Got response: " + jsonFile1);
});
}).on('error', function(e) {
done(e);
console.log("Got error: " + e.message);
});
}
app.get('/', function(req, res) {
// Map the options through the getFile function, resulting in an array of each response
async.map(httpOptions, getFile, function (err, jsonFiles) {
// You should probably check for any errors here
res.render('home', {
data: jsonFiles
});
});
});

Categories