0

I've been reading a ton about circular structures lately, but I still wonder:

How would I stringify an object like this:

var obj = {
  thas: obj,
  obj2: {
    thos: obj.obj2
  }
};
var jsonstring = JSON.stringify(obj);
alert(jsonstring);

back and forth, so that I could even already have the stringified version from the beginning and parse it all the same.

Julian Avar
  • 476
  • 1
  • 5
  • 24
  • 2
    http://stackoverflow.com/questions/9382167/serializing-object-that-contains-cyclic-object-value – Daniel Beck Jan 23 '16 at 19:51
  • 1
    That's not even a circular structure. Did you mean `obj.thas = obj.obj2.thos = obj`? – Bergi Jan 23 '16 at 19:53
  • @Bergi When I tryed to stringify it, it gave me that error, I'm using chrome v47. – Julian Avar Jan 23 '16 at 19:57
  • @julianavar: Well, it would depend a lot on what `this` is. Please show us your whole code. – Bergi Jan 23 '16 at 19:58
  • @Bergi I updated the question so you have access to the bugggy code, notice that since you are telling me that it depends on the situation(and I dont know what the different situations could be), I'm posting the entire object – Julian Avar Jan 23 '16 at 20:03
  • @DanielBeck If you check the accepted answer, you'll find a jsfiddle, go there and edit the object being stringified so that there is a third key like the following `z: this`, now try running it, does it work? Because it doesnt for me – Julian Avar Jan 23 '16 at 20:06
  • @julianavar, please give us a jsfiddle link where we can see it – Gavriel Jan 23 '16 at 20:09
  • 2
    @julianavar: I meant that [the value of `this` depends on where this expression is evaluated](http://stackoverflow.com/q/13441307/1048572) - it is **not** a [self-reference to the object literal](http://stackoverflow.com/q/4616202/1048572) as you might expect. Those 160 lines of object literal don't make me any wiser than the 6 lines you posted in the beginning. Please post the code *surrounding* this expression, and if it's a function, how/where you call it. – Bergi Jan 23 '16 at 20:10
  • @Gavriel I have edited the question so you can see what the dispute was about, and anyone else who thinks this is a duplicate. – Julian Avar Jan 23 '16 at 20:16
  • @Bergi the object is called in window object, I'm modifying it, I didnt quite understand what you meant – Julian Avar Jan 23 '16 at 20:18
  • Editing the question only makes sense if you enter some new information. @Bergi asked 26 minutes ago what do you mean on "this". You haven't answer that neither in the comments, nor in the question after you edited it. – Gavriel Jan 23 '16 at 20:22
  • @Gavriel Yes I have. I clearly stated that the object was called in the window object, and even edited the question, look at the first edit, last line of code, and last line of the edit – Julian Avar Jan 23 '16 at 20:25
  • If by "*object is called in the window object*" you mean that the assignment is evaluated in the global scope, and that `this` refers to the `window` object, then the only solution is not to reference `this` from your object. It doesn't make sense to try to stringify the global object. – Bergi Jan 23 '16 at 20:31
  • @julianavar, so if I would have a "correctly" stringified version of this object, and I send it to you via email, what would you expect to see as the value of root? Your browser's window? Or mine? ;) – Gavriel Jan 23 '16 at 20:32
  • @Bergi Wouldnt thas in the first example be equal to obj? – Julian Avar Jan 23 '16 at 20:34
  • @julianavar: No it would not. Please read the threads linked in my third comment. When you have fixed your object structure (like e.g. using the snippet from my first comment), check the suggested duplicate on how to properly serialise/deserialise it. – Bergi Jan 23 '16 at 20:36
  • The answer is you can't and you have to change your data structure. Oh and the way to make `this` refer to the thing you want it to refer to is `stringify = JSON.stringify.bind(obj.tmy.o); stringify(obj.tmy);` Of course, that still contains a circular reference and so fails. – dtanders Jan 23 '16 at 20:39
  • @dtanders thank you, I now understand – Julian Avar Jan 23 '16 at 20:41
  • @Bergi I'm sorry about the confusion, still a bit new to js and learning new things every day, anyways, thank you for your patience, yes I was refering to your first comment – Julian Avar Jan 23 '16 at 20:42

1 Answers1

1

I don't know if you have any chance to change to object hierarchy, I'd suggest a different solution for your problem:

var str = "[{\"id\": 1, \"nextId\": 2}," +
           "{\"id\": 2, \"nextId\": 3}," +
           "{\"id\": 3, \"nextId\": 1}]",
    objects = JSON.parse(str),
    cache = {};

objects.forEach(function (o, i, arr) {
    cache[o.id] = o;
});

for (var key in cache) {
    var current = cache[key];
    var next = cache[cache[key].nextId];
    current.next = next;
    next.previous = current;
}

var item = objects[0], iterations = 10;

while (iterations) {
    console.log(item.id);
    item = item.next;
    iterations--;
}

You provide ids and link to the next item via a nextId. There might be no other information needed to resolve the structure. At runtime (browser or Nodejs), you create the Object structure you need.

I hope this example helps a bit.

Florian Salihovic
  • 3,921
  • 2
  • 19
  • 26