I try to learn nodeJS and AngularJS using Clash of clan API available here https://developer.clashofclans.com/#/
My JSON api's return is truncated and i don't know how get the full response.
there is my app.js wrinting with node and express :
var express = require('express')
, https = require('https')
, bodyParser = require('body-parser')
, request = require('request')
, app = express()
, http_port = 3000;
app.use(express.static(__dirname + '/public'));
app.use(bodyParser());
var options = {
host: 'api.clashofclans.com',
port: 443,
path: '/v1/clans/' + encodeURIComponent("#PP8JC9RQ"),
headers : {
accept : "application/json",
authorization : "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiIsImtpZCI6IjI4YTMxOGY3LTAwMDAtYTFlYi03ZmExLTJjNzQzM2M2Y2NhNSJ9.eyJpc3MiOiJzdXBlcmNlbGwiLCJhdWQiOiJzdXBlcmNlbGw6Z2FtZWFwaSIsImp0aSI6ImQ4Njg1OGFhLWQzZTUtNDNiOC05MTM1LTBjNzI1ZjI4OGFiMiIsImlhdCI6MTQ1NjMwMTE5MSwic3ViIjoiZGV2ZWxvcGVyLzk1YWM0YjdmLTY5NTQtMDE3MC01ZjAyLTcxNjY1ZDMzYjUwNyIsInNjb3BlcyI6WyJjbGFzaCJdLCJsaW1pdHMiOlt7InRpZXIiOiJkZXZlbG9wZXIvc2lsdmVyIiwidHlwZSI6InRocm90dGxpbmcifSx7ImNpZHJzIjpbIjg3LjIzMS4yMTMuMTU0Il0sInR5cGUiOiJjbGllbnQifV19.SYqeSAF-0_bM1eS2-hnovvj5j-I0SQpdr_kySIiBKw9OkrNuBzZAOAOkiH3fzdKSkcHaJfXzWdXr8JozFfAmJA"
},
method: 'GET'
};
// Route par défaut
app.get("/members", function(req, res) {
console.log("-------------------------------------\n\nroot path !! Let's get clan infos from coc api\n\n-------------------------------------");
var req = https.request(options, function(response){
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
// in console JSON is full but in my html JSON is truncated..
res.send(chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.end();
});
app.listen(http_port,function(){
console.log("Listening on " + http_port);
});
If someone can teach to a nook :)
Your code is sending the first chunk of the response immediately back to the user. You need to wait until the entire HTTP response is done. Try something like this:
app.get("/members", function(req, res) {
var req = https.request(options, function(response){
var httpResult = '';
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
httpResult += chunk;
});
response.on('end', function() {
res.send(httpResult);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.end();
});
See how I append to a var each time the data event is called and when it is done - then I send the output.
Because you use send method instead write (send non-streaming). Try this:
app.get("/members", function(req, res) {
https.request(options, function(response){
response.on('data', function (chunk) {
res.write(chunk);
});
response.on('end', function () {
res.end();
});
}).end();
});
response is a stream, you can simply pipe it to res:
app.get("/members", function(req, res) {
https.request(options, function(response) {
response.pipe(res);
});
});
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 try to fetch data from different HTTP sources but I wasn't able to handle the asynchronous mode even with async...
var express = require('express');
var app = express();
var https = require("https");
var timer = require("./my_modules/timer/timer.js");
var http = require('http');
var bodyParser = require('body-parser');
var async = require('async');
var request = require('request');
//These are my source from API.
//Output is a Json file
var sources = {
cnn: 'https://newsapi.org/v1/articles?source=cnn&sortBy?&apiKey=c6b3fe2e86d54cae8dcb10dc77d5c5fc',
bbc: 'https://newsapi.org/v1/articles?source=cnn&sortBy?&apiKey=c6b3fe2e86d54cae8dcb10dc77d5c5fc',
guardian: 'https://newsapi.org/v1/articles?source=cnn&sortBy?&apiKey=c6b3fe2e86d54cae8dcb10dc77d5c5fc',
othersource: "otherurls..."
};
//I want to push the JSON object in this array
var resultArray = [];
//I setup a https GET request
var getJson = function(url) {
https.get(url, (res) => {
var body = '';
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
result = JSON.parse(body);
//push isn't working...
resultArray.push(result);
});
}).on('error', function(e) {
console.log('Got an error', e);
});
}
app.set('port', (process.env.PORT || 5000));
app.listen(
app.get('port'), () => {
console.log('We are live on port: ', app.get('port'));
getJson(sources.cnn);
});
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.use(function(req, res, next) {
res.setHeader('Content-Type', 'text/plain');
res.status(404).send('Page not found !');
res.status(503).send('Page not found, error 503');
});
console.log("resultArray:" + resultArray);
//resultArray = empty...
What should I do to push the result into my Array?
I couldn't find a way to set up a working callback function to push results into the Array.
Since you're already using the request package, have you tried something as simple as:
request({
url: sources.cnn,
json: true
}, function(error, response, body) {
var articles = body.articles;
// or by case, depending on what you want
// resultArray = resultArray.concat(articles);
resultArray.push({
cnn: articles
});
console.log(resultArray);
});
instead of writing your own getJson function?
Thanks Roby, your request is much clearer !
I have carefully read this really clear and helpful article : https://github.com/maxogden/art-of-node#callbacks
I think I got the logic :
//main function
function getJson(url, callback){
request({
url: url,
json: true,
callback:callback //added this
}, function(error, response, body) {
var articles = body.articles;
callback(articles);
});
}
//this callback function will be passed to the main function as the 2nd parameter
//it's possible to access "resultArray" ONLY from this function
var result = function(e){
resultArray.push(e);
console.log(resultArray);
};
//url and callback are passed as parameter
getJson(sources.cnn, result);
Thanks for the help
I found 2 methods to get the Post Body data in Node.js
Below is the 2 webservice Post methods, so which is preferred approach that needs to be followed while fetching the data from client through rest api in Node.js or is there any other approach to read post data.
1st Method
//http://localhost:1337/api/postparams1
//Content-Type: application/x-www-form-urlencoded
//param1=complete+reference¶m2=abcd+1234
function postparams1(req, res)
{
var result =
{
Url : req.originalUrl,
Method : req.method,
Param1 : req.body.param1,
Param2 : req.body.param2
};
res.status(200).send(result);
}
2nd Method
//http://localhost:1337/api/postparams2
//{
// "param1" : "param value 1",
// "param2" : "param value 2"
//}
function postparams2(req, res)
{
var data = '';
req.setEncoding('utf8');
req.on('data', function (chunk) {
data += chunk;
console.log("In data : " + data);
});
req.on('end', function () {
console.log("In end : " + data);
var newObj = JSON.parse(data);
newObj.Url = req.originalUrl;
newObj.Method = req.method,
res.status(200).send(newObj);
});
}
I think first option is more common beacause needs less code but you need to use Express.
Express 3 code:
app.use(express.bodyParser());
app.post('/', function(request, response){
console.log(request.body.param1);
console.log(request.body.param2);
});
Express 4 code:
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/', function(request, response){
console.log(request.body.param1);
console.log(request.body.param2);
});
See more info here:
Extract post data in node
var req = https.get("url", function(response) {
var str = ''
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log(str);
});
});
req.end();
req.on('error', function(e) {
console.error(e);
});
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.
I am using the sample code from nodejs.org and trying to send the response to the browser .
var http = require("http");
var port = 8001;
http.createServer().listen(port);
var options = {
host: "xxx",
port: 5984,
//path: "/_all_dbs",
path: "xxxxx",
method: "GET"
};
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 (chunk) {
console.log('BODY: ' + chunk);
var buffer = "";
buffer += chunk;
var parsedData = JSON.parse(buffer);
console.log(parsedData);
console.log("Name of the contact "+parsedData.name);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.write("hello");
req.end();
But req.write("hello") just does not output the string to the browser ?
Is this not the right way ? can someone also tell me how to output the response to the html in views folder so that i can populate the response to the static html .
Try this:
var http = require('http');
var options = {
host: "127.0.0.1",
port: 5984,
path: "/_all_dbs",
method: "GET"
};
http.createServer(function(req,res){
var rq = http.request(options, function(rs) {
rs.on('data', function (chunk) {
res.write(chunk);
});
rs.on('end', function () {
res.end();
});
});
rq.end();
}).listen(8001);
Edit:
This node script saves the output to a file:
var http = require('http');
var fs=require('fs');
var options = {
host: "127.0.0.1",
port: 5984,
path: "/_all_dbs",
method: "GET"
};
var buffer="";
var rq = http.request(options, function(rs) {
rs.on('data', function (chunk) {
buffer+=chunk;
});
rs.on('end', function () {
fs.writeFile('/path/to/viewsfolder/your.html',buffer,function(err){
if (err) throw err;
console.log('It\'s saved!');
});
});
});
rq.end();