2

I have used JSON.stringify() many times and I am aware of some issues such as (described in here):

  • cycles
  • too deep objects
  • too long arrays

However, I am facing incorrect stringify operation on object which is like that: enter image description here

After running JSON.stringify(obj) on console, I am getting that.

"[{"$$hashKey":"object:103",
 "ProductCategories": [{"Id":2,"ShopProductCategoryName":"Drink","isSelected":true}
                       {"Id":3,"ShopProductCategoryName":"Food","isSelected":true}]
 }]"

It only stringifies ProductCategories and $$hashKey which is totally unexpected.


Solving Attempts

If I create new object from obj and stringify it, returns correct JSON.

var newObj = { // Creates new object with same properties.
  AllProductCategories: obj.AllProductCategories,
  Id: obj.Id,
  LabelName: obj.LabelName,
  Percentages: obj.Percentages,
  ProductCategories: obj.ProductCategories
}

JSON.stringify(newObj); // Returns correct JSON.

I used the code to send object to web api compulsorily, but the way is not what I want, of course.


As I see,

  • There is no cycles.
  • It is not too deep. (only has depth 3)

Therefore, I cannot figure out what is wrong.

Community
  • 1
  • 1
dewe
  • 101
  • 2
  • 9
  • 1
    Do note that console.log is asynchronous while JSON.stringify is synchronous. Are you sure the properties you show on your screenshot (which looks to be from the console) are already present when you call stringify? – doldt Jul 06 '15 at 07:49
  • 1
    Without seeing code that replicates the issue the best we can do is throw blind guesses. – JJJ Jul 06 '15 at 07:50
  • 1
    Does it real properties, or inherited from prototype? JSON.stringify ignores prototype, while console.log shows all enumerable properties. – Alexey Ten Jul 06 '15 at 07:54
  • @Juhana there are lots of code to form an object like that, there is a problem with only `JSON.stringify(obj)`. – dewe Jul 06 '15 at 07:54
  • @doldt `console.log` isn't necessary asynchronous, see http://stackoverflow.com/a/23392650/1092711 – Pavlo Jul 06 '15 at 07:55
  • I'm sure there is, but if we can't reproduce the problem it's not really possible to solve it. – JJJ Jul 06 '15 at 07:56
  • @doldt Yeah, i'm sure because `console.log(obj)` and `JSON.stringify(obj)` successive operations. – dewe Jul 06 '15 at 07:56
  • @AlexeyTen they are real properties – dewe Jul 06 '15 at 07:59
  • Don't you have method `.toJSON`? https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON_behavior – Alexey Ten Jul 06 '15 at 08:01

1 Answers1

0

Well I suggest you create a function that clones your object without $$hashKey property that was set by angular I guess:

function cloneObj (obj) {
   var cloned = JSON.parse(JSON.stringify(obj));
   delete cloned.$$hashKey;
   for(var key in cloned) {
      if(typeof cloned[key] === 'object') {
         cloned[key] = cloneObj(cloned[key]);
      }
   }

   return cloned;
}

After you clone your object without $$hashKey, then you can stringify it without any problem.

Khalid
  • 4,730
  • 5
  • 27
  • 50
  • 2
    Angular comes with its own [`angular.toJson`](https://docs.angularjs.org/api/ng/function/angular.toJson) that leaves out the $$ properties. There's no reason to strip them out manually. – JJJ Jul 06 '15 at 08:04