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
});
});
});
Related
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.
I'm using https for this POST request.
Could someone point out the issue here? I get undefined and no error message .
I tried wrapping the request before res.write with no success. I'm getting a
statusCode: 400
Bad Payload received by generic incoming webhook.
Thanks!
connector.js
const https = require('https');
var dataString = {"text": "Hello World"};
const deets = {
portal_trade_events: {
host: "outlook.office.com",
path: "/path",
headers: {
'Content-Type': 'application/json',
'Content-Length': dataString.text.length
}
}
};
const options = {
hostname: deets.portal_trade_events.host,
port: 443,
path: deets.portal_trade_events.path,
method: 'POST',
headers: deets.portal_trade_events.headers
};
function post(options, data) {
const req = https.request(options, (res) => {
console.log(`statusCode: ${res.statusCode}`);
res.on('data', (d) => {
process.stdout.write(d)
});
});
req.on('error', (error) => {
console.error(error)
});
req.write(JSON.stringify(data));
req.end()
}
post(options, dataString);
At the very least, your headers for content-length look wrong. You're sending the full JSON, not just the one text value.
const https = require('https');
const data = JSON.stringify({
text: 'Hello World'
});
const options = {
hostname: 'outlook.office.com',
port: 443,
path: '/path',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
};
const req = https.request(options, (res) => {
console.log(`statusCode: ${res.statusCode}`);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.on('error', (error) => {
console.error(error);
});
req.write(data);
req.end();
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) {
...
How do I properly send JSON data over Http Post on NodeJS? I have checked that the data I'm sending is definitely JSON but every time I try sending over http post, it would receive an error. I cant exactly see the error as it's returning from terminal and even if I output, it's too messy, not properly formatted
var options = {
hostname: 'www.postcatcher.in',
port: 80,
path: '/catchers/5531b7faacde130300002495',
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
};
var req = http.request(options, function(res) {
console.log('Status: ' + res.statusCode);
console.log('Headers: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (body) {
console.log('Body: ' + body);
fs.writeFile("/var/www/node/test.txt", body, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
req.write('{"string": result}'); ///RESULT HERE IS A JSON
req.end();
Also tried this
// request.post(
// '',
// { form: { key: result } },
// function (error, response, body) {
// if (!error && response.statusCode == 200) {
// console.log(body);
// }
// }
// );
// console.log(result);
result is not being interpolated.
this seems to work correctly..
http = require('http');
fs = require('fs');
var options = {
hostname: 'www.postcatcher.in',
port: 80,
path: '/catchers/5531b7faacde130300002495',
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
};
var req = http.request(options, function(res) {
console.log('Status: ' + res.statusCode);
console.log('Headers: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (body) {
console.log('Body: ' + body);
fs.writeFile("test.txt", body, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
// req.write('{"string": result}'); ///RESULT HERE IS A JSON
result = '{ "hello": "json" }';
req.write('{"string": '+result+'}');
req.end();
result:
$ node 29712051.js
Status: 201
Headers: {"server":"Cowboy","date":"Sat, 18 Apr 2015 04:23:52 GMT","connection":"keep-alive","x-powered-by":"Express","content-type":"text/plain","content-length":"7","set-cookie":["connect.sid=0eGSTYI2RWf5ZTkpDZ0IumOD.OrcIJ53vFcOiQSdEbWz0ETQ9n50JBnXyZRjrSyFIdwE; path=/; expires=Sat, 18 Apr 2015 08:23:53 GMT; httpOnly"],"x-response-time":"6ms","via":"1.1 vegur"}
Body: Created
The file was saved!
$ cat test.txt
Created
actually, u can use JSON.stringify(result) to instead '{"string": '+result+'}':
http = require('http');
fs = require('fs');
var options = {
hostname: 'www.postcatcher.in',
port: 80,
path: '/catchers/5531b7faacde130300002495',
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
};
var req = http.request(options, function(res) {
console.log('Status: ' + res.statusCode);
console.log('Headers: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (body) {
console.log('Body: ' + body);
fs.writeFile("test.txt", body, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
// req.write('{"string": result}'); ///RESULT HERE IS A JSON
//
result = JSON.stringify({ hello: "json" });
req.write('{"string": '+result+'}');
//
req.end();
So I have a Node.js script and a Javascript file communicating with each other, and everything works except the Node.js is supposed to return data for an .mp3 file.
The data is binary, it looks like gibberish, how would I take that data it returns and allow the user to download it on a webpage using Javascript?
It gets data using http.responseText by the way.
Node.js Code
//initilization
var querystring = require('querystring');
var http = require('http');
var url = require('url');
var fileSystem = require('fs');
var path = require('path');
var util = require('util');
//convert function
function convert(voiceToUse, textToConvert, response)
{
console.log("Sending Convert Request...");
//data to send as a query
var data = querystring.stringify(
{
username: 'user',
password: 'pass',
action: 'convert',
voice: voiceToUse,
text: textToConvert
});
//options to use
var options = {
host: 'ws.ispeech.org',
port: 80,
path: '/api/rest/1.5',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': data.length
}
};
//http post request
var req = http.request(options, function (res)
{
res.setEncoding('utf8');
res.on('data', function (chunk)
{
console.log("Body: " + chunk);
var fileId = chunk.substr(chunk.indexOf("fileid") + 7);
console.log("Converting File...");
download(fileId.substr(0, fileId.search("&")), response);
});
});
req.on('error', function (e)
{
console.log('problem with request: ' + e.message);
});
req.write(data);
req.end();
}
//download function
function download(id, response)
{
//data to send as a query
var data = querystring.stringify(
{
username: 'user',
password: 'pass',
action: 'download',
fileid: id
});
//options to use
var options = {
host: 'ws.ispeech.org',
port: 80,
path: '/api/rest/1.5',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': data.length
}
};
//http post request
var req = http.request(options, function (res)
{
res.on('data', function (chunk)
{
if (JSON.stringify(res.headers).indexOf("audio/mp3") != -1)
{
console.log("Downloading Chunk...");
/*var fs = require('fs'),
str = 'string to append to file';
fs.open('test.mp3', 'a', 666, function (e, id)
{
fs.write(id, chunk, 0, chunk.length, 0, function ()
{
fs.close(id, function ()
{
});
});
});*/
response.write(chunk, "binary");
}
else
{
download(id, response);
}
});
res.on('end', function ()
{
if (JSON.stringify(res.headers).indexOf("audio/mp3") != -1){
response.end();
}
});
});
req.on('error', function (e)
{
console.log('problem with request: ' + e.message);
});
req.write(data);
req.end();
}
http = require('http');
fs = require('fs');
server = http.createServer( function(req, res) {
console.dir(req.param);
if (req.method == 'POST') {
console.log("POST");
var body = '';
req.on('data', function (data) {
body += data;
console.log("Partial body: " + body);
});
req.on('end', function () {
console.log("Body: " + body);
if(body){
convert('engfemale1', body, res);
res.writeHead(200, {
'Content-Type': 'audio/mp3',
'Content-Disposition': 'attachment; filename="tts.mp3"'
});
}
});
}
});
port = 8080;
server.listen(port);
console.log('Listening at port ' + port);
Javascript code
console.log('begin');
var http = new XMLHttpRequest();
var params = "text=" + bodyText;
http.open("POST", "http://supersecretserver:8080", true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//http.setRequestHeader("Content-length", params.length);
//http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {
console.log('onreadystatechange');
if (http.readyState == 4 && http.status == 200) {
alert(http.responseText);//response text is binary mp3 data
}
else {
console.log('readyState=' + http.readyState + ', status: ' + http.status);
}
}
console.log('sending...')
http.send(params);
console.log('end');
You could try using data URLs:
mp3 download
Not the best browser support though.
It is also possible to use data URLs directly in audio tags.
A better solution would be to save the mp3 on your server somewhere and return a link to it for a mp3 player to use.