xRobot
xRobot

Reputation: 26573

Why I can't retrieve json data with Nodejs?

I just need a way to retrieve json data from a specific url. I wrote this program:

'use strict';
var http = require('http');
var request = require("request");

var url = "https://restcountries.eu/rest/v2/name/united"


var server = http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});

  request({
      url: url,
      json: true
  }, function (error, response, body) {
      if (!error && response.statusCode === 200) {
         res.write(JSON.parse(body)) // Print the json response
      }else{
         res.write("error");
         res.end();
      }
  })


})

server.listen(1338, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1338/');

But I got this error:

# node mytest.js
Server running at http://127.0.0.1:1338/
undefined:1
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
 ^

SyntaxError: Unexpected token o in JSON at position 1
    at JSON.parse (<anonymous>)
    at Request._callback (/home/xxx/Nodejs/Esempi/emilianotest2.js:18:25)
    at Request.self.callback (/home/xxx/Nodejs/Esempi/node_modules/request/request.js:185:22)
    at Request.emit (events.js:160:13)
    at Request.<anonymous> (/home/xxx/Nodejs/Esempi/node_modules/request/request.js:1161:10)
    at Request.emit (events.js:160:13)
    at IncomingMessage.<anonymous> (/home/xxx/Nodejs/Esempi/node_modules/request/request.js:1083:12)
    at Object.onceWrapper (events.js:255:19)
    at IncomingMessage.emit (events.js:165:20)
    at endReadableNT (_stream_readable.js:1101:12)

Why?

EDIT:

This is the error that I get if I remove JSON.parse:

Server running at http://127.0.0.1:1338/
_http_outgoing.js:651
    throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'first argument',
    ^

TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string or Buffer
    at write_ (_http_outgoing.js:651:11)
    at ServerResponse.write (_http_outgoing.js:626:10)

Upvotes: 0

Views: 94

Answers (1)

Amadan
Amadan

Reputation: 198294

Because you gave the parameter json: true, request kindly already parsed it for you. Then when you pass the not-JSON-any-more array into JSON.parse, it gets turned into a string before it can be parsed; objects within the array get the familiar [object Object] representation, and JSON.parse chokes on it because [object Object] doesn't look like a proper array.

try {
  let json = JSON.stringify([{a:1}])
  console.log("parsed once:");
  console.log(JSON.parse(json));
  console.log("parsed twice:");
  console.log(JSON.parse(JSON.parse(json)));
} catch(e) {
  console.error(e.message);
}

EDIT: When you remove JSON.parse, you end up trying to res.write an object. res.write doesn't like that (as Roland Starke already noticed in comments); it would prefer a string:

res.write(JSON.stringify(body))

Upvotes: 2

Related Questions