Carlos Mermingas Carlos Mermingas - 3 months ago 33
TypeScript Question

Why is JSON.parse changing the values in nested arrays?

To learn Angular 2, I made a Connect Four game with Angular CLI when it used SystemJS.

I am replicating the effort from scratch with the new Webpack-based CLI and I am having a strange problem...

The following method receives a string with JSON-encoded data and initializes a new game instance with it. I added a few

console.log
to show the problem:

export class ConnectFourGameModel {
static fromJSON(jsonString: any): ConnectFourGameModel {
let jsonData = JSON.parse(jsonString);

console.log('*** from JSON (compare the "columns" array between jsonString and jsonData below) ***');
console.log('jsonString: ', jsonString);
console.log('jsonData: ', jsonData);

...
return result;
}


When this runs, the first
console.log
shows the JSON string correctly:

jsonString:
{... Several fields here ...
"columns":[[0,0,0,0,0,1],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]]
}


But the second
console.log
, which is just the result of calling
JSON.parse
on this string, seemingly randomly changes the values:

jsonData:
> Object {... Several fields here ...
> columns: Array[15]
V 0: Array[6]
0: 2 <-- Should be 0
1: 2 <-- Should be 0
2: -1 <-- Should be 0
etc...


Why is this happening?

You can probably see it better if you load the app on Github Pages, open the JavaScript console on the browser, and click on any column to make a move.

The repository is on Github: https://github.com/cmermingas/connect-four-webpack

I looked for questions here regarding parsing nested arrays with JSON.parse but I couldn't relate this issue to the ones I found.

Thanks a lot in advance!

Answer

If you put your string example into a fiddle, it appears to parse just fine:

https://jsfiddle.net/z67Lgyrm/

What is likely happening is that you are changing the data after your console.log() call. When you click the expand arrow in the log, it is actually showing the value of the object now.

Also you seem to be using slice() on the columns array, but because it is multidimensional, it is only making a copy of the the references to the child arrays (i.e. not actually copying the values).

See here for a possible solution: Create copy of multi-dimensional array, not reference - JavaScript

Comments