Unable to use tokenat on Dictionaries.

0 favourites
  • 10 posts
  • Problem Description

    Attempts to use tokenat on a Dictionary via the "For each key" event doesn't work with the dictionary.CurrentValue when I populate the Dictionary with a JSON string from a remote PHP file (via AJAX). Confirmed the code is working if I load the data from a local TXT file, loading the data from a remote PHP file don't work though.

    (Related thread: https://www.scirra.com/forum/how-do-i-use-tokenat-on-dictionaries_t184524)

    Attach a Capx

    http://n3rd.info/dictionary_tokenat_bug.capx

    Description of Capx

    1) AJAX request to a remote PHP file to get JSON formatted output of a MySQL database.

    2) Load the JSON string into a Dictionary object.

    3) Loop each Dictionary key and append the 2nd token from the CurrentValue of each key to a Text object.

    Steps to Reproduce Bug

    • Open the capx file and watch the output (no manual steps required).

    Observed Result

    Loops each key and outputs "Hello " but does not output the 2nd token like it's supposed to.

    Expected Result

    Output should be "Hello <name>" 5 times.

    Affected Browsers

    • Chrome: YES
    • FireFox: UNKNOWN (Not Installed)
    • Internet Explorer: YES
    • Edge: YES
    • Midori: YES

    Operating System and Service Pack

    Windows 10 Pro 64bit

    Construct 2 Version ID

    Tested in both r239 stable and r240 beta

  • The JSON output by your php script doesn't look like the JSON that is written by the dictionary object. Your JSON looks like this:

    {
    	"c2dictionary":true,
    	"data":[
    		["13","1","KuJoe"],
    		["14","2","TesterBot"],
    		["15","3","Hello"],
    		["16","4","Shadow"],
    		["17","6","Tinner"]
    	]
    }
    [/code:2vxyejde]
    
    Sample of working JSON that I'm using in one of my own projects:
    [code:2vxyejde]
    {
    	"c2dictionary":true,
    	"data":{
    		"100":"Course 1 Entrance",
    		"101":"Course 1-1",
    		"102":"Course 1-2",
    		"103":"Course 1-3",
    		"104":"Course 1-4",
    		"105":"Course 1-5",
    		"106":"Course 1-6",
    		"107":"Course 1-7",
    		"108":"Course 1-8",
    		"109":"Course 1-9",
    		"110":"Course 1-10"
    	}
    }
    [/code:2vxyejde]
    
    I'm not terribly well versed in JSON, but it appears you are using arrays instead of a key-value relationship, like the Dictionary expects.
  • The JSON output by your php script doesn't look like the JSON that is written by the dictionary object. Your JSON looks like this:

    > {
    	"c2dictionary":true,
    	"data":[
    > 		["13","1","KuJoe"],
    		["14","2","TesterBot"],
    		["15","3","Hello"],
    		["16","4","Shadow"],
    		["17","6","Tinner"]
    	]
    }
    [/code:2qkpa78c]
    
    Sample of working JSON that I'm using in one of my own projects:
    [code:2qkpa78c]
    {
    	"c2dictionary":true,
    	"data":{
    		"100":"Course 1 Entrance",
    		"101":"Course 1-1",
    		"102":"Course 1-2",
    		"103":"Course 1-3",
    		"104":"Course 1-4",
    		"105":"Course 1-5",
    		"106":"Course 1-6",
    		"107":"Course 1-7",
    		"108":"Course 1-8",
    		"109":"Course 1-9",
    		"110":"Course 1-10"
    	}
    }
    [/code:2qkpa78c]
    
    I'm not terribly well versed in JSON, but it appears you are using arrays instead of a key-value relationship, like the Dictionary expects.
    

    Somebody else pointed this out also which is strange because when I have a malformed JSON output and try to insert it into an Array it won't accept it. The fact that the Dictionary is accepting it (and the debug shows that the Dictionary is apparently populated correctly) has me confused. I wish there was an up-to-date example for formatting JSON output from remote files since all of the old solutions don't appear to work.

  • This can be marked as closed. It looks like the problem was me not setting the key value in my PHP output even though it automatically filled in the key values with numbers.

  • -quote snip-

    Somebody else pointed this out also which is strange because when I have a malformed JSON output and try to insert it into an Array it won't accept it. The fact that the Dictionary is accepting it (and the debug shows that the Dictionary is apparently populated correctly) has me confused. I wish there was an up-to-date example for formatting JSON output from remote files since all of the old solutions don't appear to work.

    Remember that Javascript is not a type-safe language, so if there is no run-time check to make sure that the data is valid, then it will "accept" anything. From what I know of Lua (another type-unsafe language), this sort of thing is hard to actually check at run-time, since all Lua tables (or Javascript objects, in this case) are fundamentally dictionaries at their core. Arrays are just Lua tables (or Javascript objects) with numerical keys.

    If you want a fool-proof way of determining how your data needs to be formatted, start with an empty dictionary, and use the 'Add key' action to populate it with a few entries, and then export it to JSON. It's pretty easy to figure out how to edit the JSON text to add new key-value pairs from there.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • > -quote snip-

    >

    > Somebody else pointed this out also which is strange because when I have a malformed JSON output and try to insert it into an Array it won't accept it. The fact that the Dictionary is accepting it (and the debug shows that the Dictionary is apparently populated correctly) has me confused. I wish there was an up-to-date example for formatting JSON output from remote files since all of the old solutions don't appear to work.

    >

    Remember that Javascript is not a type-safe language, so if there is no run-time check to make sure that the data is valid, then it will "accept" anything. From what I know of Lua (another type-unsafe language), this sort of thing is hard to actually check at run-time, since all Lua tables (or Javascript objects, in this case) are fundamentally dictionaries at their core. Arrays are just Lua tables (or Javascript objects) with numerical keys.

    If you want a fool-proof way of determining how your data needs to be formatted, start with an empty dictionary, and use the 'Add key' action to populate it with a few entries, and then export it to JSON. It's pretty easy to figure out how to edit the JSON text to add new key-value pairs from there.

    It's just weird that I can't use numerical keys in dictionaries. Not a huge deal but I figured it would have been posted somewhere on the forums or in the manual.

  • -quote snip-

    It's just weird that I can't use numerical keys in dictionaries. Not a huge deal but I figured it would have been posted somewhere on the forums or in the manual.

    Oh, but it is in the manual!

    The Dictionary object stores strings and numbers. Each value has an associated key, which is a string.

  • > -quote snip-

    >

    > It's just weird that I can't use numerical keys in dictionaries. Not a huge deal but I figured it would have been posted somewhere on the forums or in the manual.

    >

    Oh, but it is in the manual!

    > The Dictionary object stores strings and numbers. Each value has an associated key, which is a string.

    >

    So why does it work when my key is a word but not a number?

    This works: http://n3rd.info/upl/construct2_tokenat_works.png

    This does not: http://n3rd.info/upl/construct2_tokenat2.png

    The values are the same, the keys are the only thing that are different. This is starting to look like a bug now.

  • >

    > > -quote snip-

    > >

    > > It's just weird that I can't use numerical keys in dictionaries. Not a huge deal but I figured it would have been posted somewhere on the forums or in the manual.

    > >

    >

    > Oh, but it is in the manual!

    >

    >

    > > The Dictionary object stores strings and numbers. Each value has an associated key, which is a string.

    > >

    >

    So why does it work when my key is a word but not a number?

    This works: http://n3rd.info/upl/construct2_tokenat_works.png

    This does not: http://n3rd.info/upl/construct2_tokenat2.png

    The values are the same, the keys are the only thing that are different. This is starting to look like a bug now.

    The only 'bug' here is Construct 2 accepting whatever JSON you throw at it. Not only were you using numerical keys instead of string keys, but the values were arrays instead of numbers or strings. Construct 2's debugger is designed to print arrays by turning all of its values into strings and joining them together with commas for separators. While this may look the same as a string value, it isn't.

    Also, keep in mind that a numerical 0 key is very different from a string "0" key, even though they print the same in the debugger. This is likely why the dictionary only allows string keys.

  • OK, I was under the impression that the debugger was 100% accurate and "could do no wrong". Now it makes more sense.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)