29

In the below code (running on Node JS) I am trying to print an object obtained from an external API using JSON.stringify which results in an error:

TypeError: Converting circular structure to JSON

I have looked at the questions on this topic, but none could help. Could some one please suggest:

a) How I could obtain country value from the res object ?

b) How I could print the entire object itself ?

  http.get('http://ip-api.com/json', (res) => {     
    console.log(`Got response: ${res.statusCode}`);
    console.log(res.country)  // *** Results in Undefined
    console.log(JSON.stringify(res)); // *** Resulting in a TypeError: Converting circular structure to JSON

    res.resume();
  }).on('error', (e) => {
    console.log(`Got error: ${e.message}`);
  });
kurrodu
  • 2,108
  • 4
  • 32
  • 49
  • 1
    http://stackoverflow.com/questions/4816099/chrome-sendrequest-error-typeerror-converting-circular-structure-to-json – XCS Aug 04 '16 at 13:23
  • 1
    Do you use body-parser? `res.country` shouldn't be undefined. – XCS Aug 04 '16 at 13:25
  • @Cristy I am not using body-parser; res.country prints as undefined. Not sure why it does that ? – kurrodu Aug 04 '16 at 13:41

8 Answers8

52

Basic console.log will not go through long and complex object, and may decide to just print [Object] instead.

A good way to prevent that in node.js is to use util.inspect:

'use strict';
const util = require('util'),
    obj = /*Long and complex object*/;

console.log(util.inspect(obj, {depth: null}));
//depth: null tell util.inspect to open everything until it get to a circular reference, the result can be quite long however.

EDIT: In a pinch (in the REPL for example), a second option is JSON.stringify. No need to require it, but it will break on circular reference instead of printing the fact there is a reference.

DrakaSAN
  • 7,673
  • 7
  • 52
  • 94
3

Print the whole object, it will not have problems with recursive refferences:

console.log(res);

Here's an example for you to see how console.log handles circular refferences:

> var q = {a:0, b:0}
> q.b = q
> console.log(q)
{ a: 0, b: [Circular] }

Also, I would advise to check what data are you actually receiving.

Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • console.log(res) prints our very long data, that contains config info on 'scoket', 'ReadableState', 'WritableState', 'ClientRequest', 'Connection' etc.. It does not contain the JSON response I am looking for. – kurrodu Aug 04 '16 at 13:36
  • It contain the whole `HTTP response` object, as indicated in the Express doc. You should try to print `res.body`, or sift throught the whole object. – DrakaSAN Aug 04 '16 at 13:39
  • @DrakaSAN printing ' res.body' results in -> undefined ; I searched the entire object for keys (country, region) but none of them are present. – kurrodu Aug 04 '16 at 13:46
  • @kurrodu I'm not sure what do you expect of me. You didn't even mention what HTTP library are you using to get that data, how the hell am I supposed to know where can you find it. The fact that `console.log(res) prints our very long data,` does not really explain the problem to me. Just copy the data to text editor and find what you need. Or read your HTTP librarie's documentation. – Tomáš Zato Aug 04 '16 at 13:55
  • Sorry, If I wasn't clear. I copied the data into text editor but it doesn't contain the JSON response I am looking for. I am using the http.get method as shown in the these docs https://nodejs.org/api/http.html#http_http_methods – kurrodu Aug 04 '16 at 14:04
  • 1
    @kurrodu You asked question "How to print object in Node JS". Not "I can't get my JSON request to work". I told you to check what data is server sending. Did you do that? If you can't see the JSON in the response, maybe it's not there. Either case, you did not share proper info in your question. You should do proper research and tests with your code and ask another question about the actual problem you have. – Tomáš Zato Aug 04 '16 at 14:12
3

By using the http request client, I am able to print the JSON object as well as print the country value. Below is my updated code.

var request = require('request');
request('http://ip-api.com/json', function (error, response, body) {
  if (!error && response.statusCode == 200) {
    console.log(response.body);    // Prints the JSON object
    var object = JSON.parse(body);
    console.log(object['country']) // Prints the country value from the JSON object
  }
});
kurrodu
  • 2,108
  • 4
  • 32
  • 49
2

This can print the key of the object and the value of the object in the simplest way. Just try it.

const jsonObj = {
  a: 'somestring',
  b: 42,
  c: false
};

Array.from(Object.keys(jsonObj)).forEach(function(key){
  console.log(key + ":" + jsonObj[key]);
});
zemunkh
  • 662
  • 7
  • 13
2

In 2021, I just printed using

app.post("/",(req,res) => {
    console.log("HI "+JSON.stringify(req.body));
    res.send("Hi")
});

and got my output as HI {"Hi":"Hi"}.

I sent

{
    "Hi": "Hi"
}

as my post request body.

Only doing console.log(req.body) printed [object Object] on console but now this works.

Wilfred Almeida
  • 601
  • 8
  • 15
1

Use console.dir and set the depth.

console.dir(obj, { depth:10 })

Alternatively you can set the default depth to change the console.log depth.

require('util').inspect.defaultOptions.depth = 10

All of this and details about this can be found in nodejs training.

https://nodejs.dev/learn/how-to-log-an-object-in-nodejs

Michael Warner
  • 3,879
  • 3
  • 21
  • 45
0

You do not actually get data in res. You need on('data') and on.('end')

body is a string. It gets append on data received, so on complete you will need to parse data into json

http.get("http://ip-api.com/json", function(res) {
    var body = '';
    res.on('data', function(data){
        body = body + data;
    });

    res.on('end', function() {
        var parsed = {};  
        try{
            parsed = JSON.parse(body); // i have checked its working correctly
        }
        catch(er){
            //do nothing it is already json
        }
        console.log(parsed.country);
    });
});

Noe from parsed which is a json object, you can get any property

Sami
  • 8,168
  • 9
  • 66
  • 99
0

You can pass two arguments to console.log()

Try this code after installing "yargs" And it will print whole object

console.log('object is' , yargs.argv);

I think may be it will help you to print whole object :)

black hat
  • 1
  • 1