user680174
user680174

Reputation: 12391

Converting an object to a string

How can I convert a JavaScript object into a string?

Example:

var o = {a:1, b:2}
console.log(o)
console.log('Item: ' + o)

Output:

Object { a=1, b=2} // very nice readable output :)
Item: [object Object] // no idea what's inside :(

Upvotes: 1239

Views: 2412537

Answers (30)

Alexandre Crivellaro
Alexandre Crivellaro

Reputation: 893

Use the key, value;

var o = {a:1, b:2}
var s = "";
for (r in o) {
    s += r + ":" + o[r] + ";";
}

Result: s = a:1;b:2;

Upvotes: 0

Marc Guvenc
Marc Guvenc

Reputation: 81

This is in Angular 15:

registerForm = new FormGroup({
  fname1: new FormControl(""),
  lname1: new FormControl(""),
  address1: new FormControl(""),
  address2: new FormControl(""),
  city1: new FormControl(""),
  state1: new FormControl(""),
  zip1: new FormControl("")

});

registerSubmited() {
alert(this.registerForm.value.fname1);
alert(this.registerForm.value.lname1);
alert(this.registerForm.value.address1);
alert(this.registerForm.value.address2);
alert(this.registerForm.value.city1);
alert(this.registerForm.value.state1);
alert(this.registerForm.value.zip1);
}

Upvotes: 0

Gary Chambers
Gary Chambers

Reputation: 25868

I would recommend using JSON.stringify, which converts the set of the variables in the object to a JSON string.

var obj = {
  name: 'myObj'
};

JSON.stringify(obj);

Most modern browsers support this method natively, but for those that don't, you can include a JS version.

Upvotes: 1665

Durdona A.
Durdona A.

Reputation: 318

I used for in and template literal to have both key-value pairs in string and it worked for me.

let obj = {
  name: "John",
  age: 22,
  isDev: true,
};
let toStr = "";
for (let key in obj) {
  if (obj.hasOwnProperty(key)) {
    toStr += `${key} ${obj[key]}` + ", ";
  }
}
console.log(toStr);
console.log(typeof toStr);

Upvotes: 1

loretoparisi
loretoparisi

Reputation: 16309

A modified approach using reduce that let to change the separator sep between (key,value) tuple while checking last item:

/**
     * Object to string
     * @param {*} obj 
     * @param {*} k_sep keys separator
     * @param {*} v_sep values separator
     * @returns 
     */
    var objectToString: function (obj, k_sep = '=', v_sep = ',') {
      const entries = Object.entries(obj);
      return entries.reduce((str, [p, val], counter) => {
        if (counter < entries.length - 1) {
          return `${str}${p}${k_sep}${val}${v_sep}`;
        } else {
          return `${str}${p}${k_sep}${val}`;
        }
      }, '');
    }

/**
 * Object to string
 * @param {*} obj 
 * @param {*} k_sep keys separator
 * @param {*} v_sep values separator
 * @returns 
 */
var objectToString = function(obj, k_sep = '=', v_sep = ',') {
  const entries = Object.entries(obj);
  return entries.reduce((str, [p, val], counter) => {
    if (counter < entries.length - 1) {
      return `${str}${p}${k_sep}${val}${v_sep}`;
    } else {
      return `${str}${p}${k_sep}${val}`;
    }
  }, '');
}

console.log(
  objectToString({
    status_code: 200,
    execute_time: 0.1,
    ip: '1270.0.0.1'
  }, ':', ","))
console.log(
  objectToString({
    status_code: 200,
    execute_time: 0.1,
    ip: '1270.0.0.1'
  }, '=', ","))

Upvotes: 1

Eve
Eve

Reputation: 377

Some simple solution is the one below.

It only displays "" for strings, not for numbers and functions/methods (if the methods are written as shown here):

  let obj = {
        name: "Philips TV",
        price: 2500,
        somemethod: function() {return "Hi there"}
  };
  
  let readableobj = '{ ';
  
  for(key in obj) {
    readableobj +=
    (typeof obj[key] === "string")? `${key}: "${obj[key]}", ` : `${key}: ${obj[key]}, `;
  }
 
  readableobj += '}';
  
  console.log('obj', readableobj); // obj { name: "Philips TV", price: 42, somemethod: function() {return "Hi there"}, }

This solution uses trailing commas (which are legal since ECMAScript 5 - see reference here in MDN.)

The code is based on simplest form of a 'for in' loop:

let obj = {key: "value"};
for(key in obj) {
    return "The property " + key + " with value " + obj[key];
}

Note: It even works for this kind of method notation:

  let obj = {
        name: "Philips TV",
        price: 2500,
        somemethod() {return "Hi there"}
  };

displaying the result as

    obj { name: "Philips TV", price: 42, somemethod: somemethod() {return "Hi there"}, } 

and even for arrow function notation

  let obj = {
        name: "Philips TV",
        price: 2500,
        somemethod: () => {return "Hi there"}
  };

displaying the result as

    obj { name: "Philips TV", price: 42, somemethod: () => {return "Hi there"}, }

Therefore, you could display in an acceptable format even an object having inside it all three forms of method notations, like this one:

  let obj = {
        name: "Philips TV",
        price: 2500,
        method1: function() {return "Hi there"},
        method2() {return "Hi there"},
        method3: () => {return "Hi there"}
  };

One might see that even the second format method2() {return "Hi there"} is also eventually displayed as a pair key: value as well, by duplicating its identifier

// method2: method2() {return "Hi there"}

Finally, true / false, undefined, null are treated in the same way as numbers and functions (with no "" shown in the final format) because they are not strings, either.

IMPORTANT:

JSON.stringify() destroys the original object in the meaning that the methods are lost and not shown in the final string created by it.

Therefore we probably shouldn't accept solutions involving its use.

console.log('obj', JSON.stringify(obj)); // obj {"name":"Philips TV","price":2500} // which is NOT acceptable

Upvotes: 1

Phillip Senn
Phillip Senn

Reputation: 47643

If the object is a jQuery object, then you should use:

obj.html()

instead of:

JSON.stringify(obj)

Example:

var tr = $('tr')

console.log('This does not work:')
console.log(JSON.stringify(tr))
console.log('But this does:')
console.log(tr.html())
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr><td>a</td><td>b</td>
</table>

Upvotes: -1

Brett Zamir
Brett Zamir

Reputation: 14375

Sure, to convert an object into a string, you either have to use your own method, such as:

function objToString (obj) {
    var str = '';
    for (var p in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, p)) {
            str += p + '::' + obj[p] + '\n';
        }
    }
    return str;
}

Actually, the above just shows the general approach; you may wish to use something like http://phpjs.org/functions/var_export:578 or http://phpjs.org/functions/var_dump:604

or, if you are not using methods (functions as properties of your object), you may be able to use the new standard (but not implemented in older browsers, though you can find a utility to help with it for them too), JSON.stringify(). But again, that won't work if the object uses functions or other properties which aren't serializable to JSON.

Update:

A more modern solution would be:

function objToString (obj) {
    let str = '';
    for (const [p, val] of Object.entries(obj)) {
        str += `${p}::${val}\n`;
    }
    return str;
}

or:

function objToString (obj) {
    return Object.entries(obj).reduce((str, [p, val]) => {
        return `${str}${p}::${val}\n`;
    }, '');
}

Upvotes: 106

Gazler
Gazler

Reputation: 84190

EDIT Do not use this answer as it works only in some versions of Firefox. No other browsers support it. Use Gary Chambers solution.

toSource() is the function you are looking for which will write it out as JSON.

var object = {};
object.first = "test";
object.second = "test2";
alert(object.toSource());

Upvotes: 39

Shashwat Gupta
Shashwat Gupta

Reputation: 5272

maybe you are looking for

JSON.stringify(JSON.stringify(obj))


"{\"id\":30}"

Upvotes: 5

chaya D
chaya D

Reputation: 161

add on ---

JSON.stringify(obj) is nice, but it will convert to json string object. sometimes we will need the string of it, like when posting it in body for WCF http post and recieving as a string.

in order of this we should reuse the stringify() as following:

let obj = {id:1, name:'cherry'};
let jsonObj = JSON.stringify(doc); //json object string
let strObj = JSON.stringify(jsonObj); //json object string wrapped with string

Upvotes: 1

Kamil Kiełczewski
Kamil Kiełczewski

Reputation: 92725

Circular References

By using below replacer we can produce less redundant JSON - if source object contains multi-references to some object, or contains circular references - then we reference it by special path-string (similar to JSONPath) - we use it as follows

let s = JSON.stringify(obj, refReplacer());

function refReplacer() {
  let m = new Map(), v= new Map(), init = null;

  return function(field, value) {
    let p= m.get(this) + (Array.isArray(this) ? `[${field}]` : '.' + field); 
    let isComplex= value===Object(value)
    
    if (isComplex) m.set(value, p);  
    
    let pp = v.get(value)||'';
    let path = p.replace(/undefined\.\.?/,'');
    let val = pp ? `#REF:${pp[0]=='[' ? '$':'$.'}${pp}` : value;
    
    !init ? (init=value) : (val===init ? val="#REF:$" : 0);
    if(!pp && isComplex) v.set(value, path);
   
    return val;
  }
}




// ---------------
// TEST
// ---------------

// gen obj with duplicate references
let a = { a1: 1, a2: 2 };
let b = { b1: 3, b2: "4" };
let obj = { o1: { o2:  a  }, b, a }; // duplicate reference
a.a3 = [1,2,b];                      // circular reference
b.b3 = a;                            // circular reference


let s = JSON.stringify(obj, refReplacer(), 4);

console.log(s);

BONUS: and here is inverse function of such serialisation

function parseRefJSON(json) {
  let objToPath = new Map();
  let pathToObj = new Map();
  let o = JSON.parse(json);
  
  let traverse = (parent, field) => {
    let obj = parent;
    let path = '#REF:$';

    if (field !== undefined) {
      obj = parent[field];
      path = objToPath.get(parent) + (Array.isArray(parent) ? `[${field}]` : `${field?'.'+field:''}`);
    }

    objToPath.set(obj, path);
    pathToObj.set(path, obj);
    
    let ref = pathToObj.get(obj);
    if (ref) parent[field] = ref;

    for (let f in obj) if (obj === Object(obj)) traverse(obj, f);
  }
  
  traverse(o);
  return o;
}



// ------------
// TEST
// ------------

let s = `{
    "o1": {
        "o2": {
            "a1": 1,
            "a2": 2,
            "a3": [
                1,
                2,
                {
                    "b1": 3,
                    "b2": "4",
                    "b3": "#REF:$.o1.o2"
                }
            ]
        }
    },
    "b": "#REF:$.o1.o2.a3[2]",
    "a": "#REF:$.o1.o2"
}`;

console.log('Open Chrome console to see nested fields:');
let obj = parseRefJSON(s);

console.log(obj);

Upvotes: 2

Vikram Pote
Vikram Pote

Reputation: 5579

Use javascript String() function

 String(yourobject); //returns [object Object]

or stringify()

JSON.stringify(yourobject)

Upvotes: 181

Gleb Dolzikov
Gleb Dolzikov

Reputation: 834

It appears JSON accept the second parameter that could help with functions - replacer, this solves the issue of converting in the most elegant way:

JSON.stringify(object, (key, val) => {
    if (typeof val === 'function') {
      return String(val);
    }
    return val;
  });

Upvotes: 10

Christian Gawron
Christian Gawron

Reputation: 841

There is actually one easy option (for recent browsers and Node.js) missing in the existing answers:

console.log('Item: %o', o);

I would prefer this as JSON.stringify() has certain limitations (e.g. with circular structures).

Upvotes: 14

Moe
Moe

Reputation: 129

If all you want is to simply get a string output, then this should work: String(object)

Upvotes: -1

nanobar
nanobar

Reputation: 66455

I had need to make a more configurable version of JSON.stringify as I had to add comments and know the JSON path:

const someObj = {
  a: {
    nested: {
      value: 'apple',
    },
    sibling: 'peanut'
  },
  b: {
    languages: ['en', 'de', 'fr'],
    c: {
      nice: 'heh'
    }
  },
  c: 'butter',
  d: function () {}
};

function* objIter(obj, indent = '  ', depth = 0, path = '') {
  const t = indent.repeat(depth);
  const t1 = indent.repeat(depth + 1);
  const v = v => JSON.stringify(v);
  yield { type: Array.isArray(obj) ? 'OPEN_ARR' : 'OPEN_OBJ', indent, depth };
  const keys = Object.keys(obj);
  
  for (let i = 0, l = keys.length; i < l; i++) {
    const key = keys[i];
    const prop = obj[key];
    const nextPath = !path && key || `${path}.${key}`;
 
    if (typeof prop !== 'object') {
      yield { type:  isNaN(key) ? 'VAL' : 'ARR_VAL', key, prop, indent, depth, path: nextPath };
    } else {
      yield { type: 'OBJ_KEY', key, indent, depth, path: nextPath };
      yield* objIter(prop, indent, depth + 1, nextPath);
    }
  }

  yield { type: Array.isArray(obj) ? 'CLOSE_ARR' : 'CLOSE_OBJ', indent, depth };
}

const iterMap = (it, mapFn) => {
  const arr = [];
  for (const x of it) { arr.push(mapFn(x)) }
  return arr;
}

const objToStr = obj => iterMap(objIter(obj), ({ type, key, prop, indent, depth, path }) => {
  const t = indent.repeat(depth);
  const t1 = indent.repeat(depth + 1);
  const v = v => JSON.stringify(v);

  switch (type) {
    case 'OPEN_ARR':
      return '[\n';
    case 'OPEN_OBJ':
      return '{\n';
    case 'VAL':
      return `${t1}// ${path}\n${t1}${v(key)}: ${v(prop)},\n`;
    case 'ARR_VAL':
      return `${t1}// ${path}\n${t1}${v(prop)},\n`;
    case 'OBJ_KEY':
      return `${t1}// ${path}\n${t1}${v(key)}: `;
    case 'CLOSE_ARR':
    case 'CLOSE_OBJ':
      return `${t}${type === 'CLOSE_ARR' ? ']' : '}'}${depth ? ',' : ';'}\n`;
    default:
      throw new Error('Unknown type:', type);
  }
}).join('');

const s = objToStr(someObj);
console.log(s);

Upvotes: 1

Nicolas Zozol
Nicolas Zozol

Reputation: 7048

stringify-object is a good npm library made by the yeoman team: https://www.npmjs.com/package/stringify-object

npm install stringify-object

then:

const stringifyObject = require('stringify-object');
stringifyObject(myCircularObject);

Obviously it's interesting only if you have circular object that would fail with JSON.stringify();

Upvotes: 7

stackuser83
stackuser83

Reputation: 2240

If you want a minimalist method of converting a variable to a string for an inline expression type situation, ''+variablename is the best I have golfed.

If 'variablename' is an object and you use the empty string concatenation operation, it will give the annoying [object Object], in which case you probably want Gary C.'s enormously upvoted JSON.stringify answer to the posted question, which you can read about on Mozilla's Developer Network at the link in that answer at the top.

Upvotes: 0

Alex Sz&#252;cs
Alex Sz&#252;cs

Reputation: 681

For non-nested objects:

Object.entries(o).map(x=>x.join(":")).join("\r\n")

Upvotes: 9

Илья Индиго
Илья Индиго

Reputation: 111

If you wont aplay join() to Object.

const obj = {one:1, two:2, three:3};
let arr = [];
for(let p in obj)
    arr.push(obj[p]);
const str = arr.join(',');

Upvotes: 1

vacsati
vacsati

Reputation: 567

1.

JSON.stringify(o);

Item: {"a":"1", "b":"2"}

2.

var o = {a:1, b:2};
var b=[]; Object.keys(o).forEach(function(k){b.push(k+":"+o[k]);});
b="{"+b.join(', ')+"}";
console.log('Item: ' + b);

Item: {a:1, b:2}

Upvotes: 10

kwarnke
kwarnke

Reputation: 1524

If you can use lodash you can do it this way:

> var o = {a:1, b:2};
> '{' + _.map(o, (value, key) => key + ':' + value).join(', ') + '}'
'{a:1, b:2}'

With lodash map() you can iterate over Objects as well. This maps every key/value entry to its string representation:

> _.map(o, (value, key) => key + ':' + value)
[ 'a:1', 'b:2' ]

And join() put the array entries together.

If you can use ES6 Template String, this works also:

> `{${_.map(o, (value, key) => `${key}:${value}`).join(', ')}}`
'{a:1, b:2}'

Please note this do not goes recursive through the Object:

> var o = {a:1, b:{c:2}}
> _.map(o, (value, key) => `${key}:${value}`)
[ 'a:1', 'b:[object Object]' ]

Like node's util.inspect() will do:

> util.inspect(o)
'{ a: 1, b: { c: 2 } }'

Upvotes: 3

sunny rai
sunny rai

Reputation: 615

var obj={
name:'xyz',
Address:'123, Somestreet'
 }
var convertedString=JSON.stringify(obj) 
 console.log("literal object is",obj ,typeof obj);
 console.log("converted string :",convertedString);
 console.log(" convertedString type:",typeof convertedString);

Upvotes: 15

Alex
Alex

Reputation: 29

var o = {a:1, b:2};

o.toString=function(){
  return 'a='+this.a+', b='+this.b;
};

console.log(o);
console.log('Item: ' + o);

Since Javascript v1.0 works everywhere (even IE) this is a native approach and allows for a very costomised look of your object while debugging and in production https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/toString

Usefull example

var Ship=function(n,x,y){
  this.name = n;
  this.x = x;
  this.y = y;
};
Ship.prototype.toString=function(){
  return '"'+this.name+'" located at: x:'+this.x+' y:'+this.y;
};

alert([new Ship('Star Destroyer', 50.001, 53.201),
new Ship('Millennium Falcon', 123.987, 287.543),
new Ship('TIE fighter', 83.060, 102.523)].join('\n'));//now they can battle!
//"Star Destroyer" located at: x:50.001 y:53.201
//"Millennium Falcon" located at: x:123.987 y:287.543
//"TIE fighter" located at: x:83.06 y:102.523

Also, as a bonus

function ISO8601Date(){
  return this.getFullYear()+'-'+(this.getMonth()+1)+'-'+this.getDate();
}
var d=new Date();
d.toString=ISO8601Date;//demonstrates altering native object behaviour
alert(d);
//IE6   Fri Jul 29 04:21:26 UTC+1200 2016
//FF&GC Fri Jul 29 2016 04:21:26 GMT+1200 (New Zealand Standard Time)
//d.toString=ISO8601Date; 2016-7-29

Upvotes: 2

Khushal Chheda
Khushal Chheda

Reputation: 68

I hope this example will help for all those who all are working on array of objects

var data_array = [{
                    "id": "0",
                    "store": "ABC"
                },{
                    "id":"1",
                    "store":"XYZ"
                }];
console.log(String(data_array[1]["id"]+data_array[1]["store"]));

Upvotes: 1

Mauro
Mauro

Reputation: 21

function objToString (obj) {
    var str = '{';
    if(typeof obj=='object')
      {

        for (var p in obj) {
          if (obj.hasOwnProperty(p)) {
              str += p + ':' + objToString (obj[p]) + ',';
          }
      }
    }
      else
      {
         if(typeof obj=='string')
          {
            return '"'+obj+'"';
          }
          else
          {
            return obj+'';
          }
      }



    return str.substring(0,str.length-1)+"}";
}

Upvotes: 2

Anuraag Vaidya
Anuraag Vaidya

Reputation: 847

If you only care about strings, objects, and arrays:

function objectToString (obj) {
        var str = '';
        var i=0;
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                if(typeof obj[key] == 'object')
                {
                    if(obj[key] instanceof Array)
                    {
                        str+= key + ' : [ ';
                        for(var j=0;j<obj[key].length;j++)
                        {
                            if(typeof obj[key][j]=='object') {
                                str += '{' + objectToString(obj[key][j]) + (j > 0 ? ',' : '') + '}';
                            }
                            else
                            {
                                str += '\'' + obj[key][j] + '\'' + (j > 0 ? ',' : ''); //non objects would be represented as strings
                            }
                        }
                        str+= ']' + (i > 0 ? ',' : '')
                    }
                    else
                    {
                        str += key + ' : { ' + objectToString(obj[key]) + '} ' + (i > 0 ? ',' : '');
                    }
                }
                else {
                    str +=key + ':\'' + obj[key] + '\'' + (i > 0 ? ',' : '');
                }
                i++;
            }
        }
        return str;
    }

Upvotes: 5

Houshalter
Houshalter

Reputation: 2798

None of the solutions here worked for me. JSON.stringify seems to be what a lot of people say, but it cuts out functions and seems pretty broken for some objects and arrays I tried when testing it.

I made my own solution which works in Chrome at least. Posting it here so anyone that looks this up on Google can find it.

//Make an object a string that evaluates to an equivalent object
//  Note that eval() seems tricky and sometimes you have to do
//  something like eval("a = " + yourString), then use the value
//  of a.
//
//  Also this leaves extra commas after everything, but JavaScript
//  ignores them.
function convertToText(obj) {
    //create an array that will later be joined into a string.
    var string = [];

    //is object
    //    Both arrays and objects seem to return "object"
    //    when typeof(obj) is applied to them. So instead
    //    I am checking to see if they have the property
    //    join, which normal objects don't have but
    //    arrays do.
    if (typeof(obj) == "object" && (obj.join == undefined)) {
        string.push("{");
        for (prop in obj) {
            string.push(prop, ": ", convertToText(obj[prop]), ",");
        };
        string.push("}");

    //is array
    } else if (typeof(obj) == "object" && !(obj.join == undefined)) {
        string.push("[")
        for(prop in obj) {
            string.push(convertToText(obj[prop]), ",");
        }
        string.push("]")

    //is function
    } else if (typeof(obj) == "function") {
        string.push(obj.toString())

    //all other values can be done with JSON.stringify
    } else {
        string.push(JSON.stringify(obj))
    }

    return string.join("")
}

EDIT: I know this code can be improved but just never got around to doing it. User andrey suggested an improvement here with the comment:

Here is a little bit changed code, which can handle 'null' and 'undefined', and also do not add excessive commas.

Use that at your own risk as I haven't verified it at all. Feel free to suggest any additional improvements as a comment.

Upvotes: 26

Fuzzyzilla
Fuzzyzilla

Reputation: 356

For your example, I think console.log("Item:",o) would be easiest. But, console.log("Item:" + o.toString) would also work.

Using method number one uses a nice dropdown in the console, so a long object would work nicely.

Upvotes: 1

Related Questions