Jump to content

getJSON clone


Recommended Posts

* If you don't want to read this background, jump to the question below.

I have awards in a game and when you win each award, I mark that award in JSON object and saved it in localStorage.

Those awards are loaded from JSON file on a server using game.cache.getJSON function. I also give the player option to clear the awards and start all over again.

I have a global gameJSON variable where the initial JSON is loaded, where I change which award is won and gameJSON is saved to localStorage.

At first, I had a problem when I was clearing the localStorage and then reloading JSON from the server for a fresh start and by visiting awards list, found out like they are never deleted, unless I refresh.
I've searched and found in documentation that getJSON returns a reference and not a copy of a JSON object and if you changed it, you change it in the cache too, but there's a second argument to clone it which solved that problem.


So I've set getJSON second argument to true (to clone it) instead of passing it as a reference and when I was inspecting gameJSON object to verify it works, it did work, but I've noticed some other functions and JSON object is not like when I was loading it without cloning and awards display wasn't working. (no errors though)

My question is how to clone/copy it without those extra function? I just need my JSON string.


Link to comment
Share on other sites

getJSON(key) and getJSON(key, true) doesn't return the same object.

First one returns JSON object which I expect, but because getJSON(key) returns a reference to that object and if I change it, next time when I call getJSON(key) I get that changed JSON and I want initial JSON so that I can clear the awards that user has won.
The second one returns an object by a value and if I modify it, it doesn't change the one in the cache (which I also want), but when I output getJSON(key, true) to the console, I get my JSON object along with some functions I don't need which breaks my function for displaying the awards.

My question was how to clone/copy JSON without those extra function, just with JSON object like with the first function?

I can create a fiddle to showcase the difference between getJSON(key) and getJSON(key, true) if I didn't explained it well.

Link to comment
Share on other sites

Here's the fiddle - https://jsfiddle.net/1ypcnre5/

And from the Phaser documentation about getJSON


Understand that almost without exception when you get an item from the cache it will return a reference to the item stored in the cache, not a copy of it. Therefore if you retrieve an item and then modify it, the original object in the cache will also be updated, even if you don't put it back into the cache again.

getJSON function have second argument for cloning the object, but it also return some other functions, not just JSON object.

I hope it's much clearer now.

Link to comment
Share on other sites

It is! You've got a bug in getJSON(true, 'key'). I'll file an issue on the GitHub repo and include your really good recreation. Thanks for that JSFiddle, that made it really clear.

It looks to me like getJSON(true, 'key') is not just including your object but also adding all the Phaser.Utils methods to the object (chanceRoll, extend, isPlainObject, etc). Pretty sure it's because of this line in Phaser.Utils.extend: https://github.com/photonstorm/phaser/blob/9f28d0659daaed07a15bc45ef39d89b97f3f3ecf/src/utils/Utils.js#L251

See where it says "target = this;"? "this" in this case (ha) is Phaser.Utils. This whole function looks like it's meant to be variadic and take a whole list of objects. Which I *think* means that this line https://github.com/photonstorm/phaser/blob/9f28d0659daaed07a15bc45ef39d89b97f3f3ecf/src/loader/Cache.js#L1315 should maybe read "return Phaser.Utils.extend(true, {}, data);" instead?

Link to comment
Share on other sites

Sorry for delayed answer.

I've downloaded the dev branch, replaced phaser.js with the new one and it is not working.
Length property of the JSON object is missing and __proto__ of the JSON object has different functions than the JSON object returned with getJSON(key).

Here's the screenshoot


Link to comment
Share on other sites

Sorry it's not working! What "Length" property? Those functions under "__proto__" are the default Object functions in JavaScript, available on every JS object: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype

If you're iterating through this object in ES5, you need to call "hasOwnProperty" to skip these methods (maybe probably). 

Link to comment
Share on other sites

I am iterating through JSON from i = 0 to JSON.length. This length property is available when using getJSON(key), but it is not available with getJSON(key, true) and because of that, JSON.length is undefined, code did not enter the loop and nothing is displayed.

I've mentioned those __proto__ functions because they are different between getJSON(key) and getJSON(key, true). It that's how it supposed to be, than it's ok.

Here's screenshoot.


Link to comment
Share on other sites

Here's a jsbin: http://jsbin.com/gahomu/edit?html,js,console

In there, I'm not seeing what you're describing using the latest dev build from GitHub. The "thing" object is an Array in the console and has a length property and one of the Array methods. Do you have a live example somewhere that reproduces this using your code?

Link to comment
Share on other sites

There's no problem when using getJSON(key) function.
Problem is when the second argument of the getJSON function is set to true (this.cache.getJSON('thing', true)).

You can reproduce this with jsbin you've created.
Set the second argument to true and run the code. You will notice that thing.length is undefined.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...