Unable to use tokenat on Dictionaries.

Bugs will be moved here once resolved.

Post » Sat Nov 26, 2016 7:34 am

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
B
10
S
2
G
2
Posts: 13
Reputation: 1,576

Post » Sat Nov 26, 2016 11:09 pm

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:
Code: Select all
{
   "c2dictionary":true,
   "data":[
      ["13","1","KuJoe"],
      ["14","2","TesterBot"],
      ["15","3","Hello"],
      ["16","4","Shadow"],
      ["17","6","Tinner"]
   ]
}


Sample of working JSON that I'm using in one of my own projects:
Code: Select all
{
   "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"
   }
}


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.
B
54
S
19
G
13
Posts: 97
Reputation: 10,146

Post » Sun Nov 27, 2016 2:10 am

Johncw87 wrote: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:
Code: Select all
{
   "c2dictionary":true,
   "data":[
      ["13","1","KuJoe"],
      ["14","2","TesterBot"],
      ["15","3","Hello"],
      ["16","4","Shadow"],
      ["17","6","Tinner"]
   ]
}


Sample of working JSON that I'm using in one of my own projects:
Code: Select all
{
   "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"
   }
}


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.
B
10
S
2
G
2
Posts: 13
Reputation: 1,576

Post » Sun Nov 27, 2016 9:46 am

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.
B
10
S
2
G
2
Posts: 13
Reputation: 1,576

Post » Sun Nov 27, 2016 9:48 am

KuJoe wrote:-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.
B
54
S
19
G
13
Posts: 97
Reputation: 10,146

Post » Mon Nov 28, 2016 4:38 am

Johncw87 wrote:
KuJoe wrote:-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.
B
10
S
2
G
2
Posts: 13
Reputation: 1,576

Post » Mon Nov 28, 2016 4:58 am

KuJoe wrote:-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 Manual wrote:The Dictionary object stores strings and numbers. Each value has an associated key, which is a string.
B
54
S
19
G
13
Posts: 97
Reputation: 10,146

Post » Mon Nov 28, 2016 11:54 am

Johncw87 wrote:
KuJoe wrote:-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 Manual wrote: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.
B
10
S
2
G
2
Posts: 13
Reputation: 1,576

Post » Tue Nov 29, 2016 4:00 pm

KuJoe wrote:
Johncw87 wrote:
KuJoe wrote:-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 Manual wrote: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.
B
54
S
19
G
13
Posts: 97
Reputation: 10,146

Post » Tue Nov 29, 2016 11:57 pm

OK, I was under the impression that the debugger was 100% accurate and "could do no wrong". Now it makes more sense.
B
10
S
2
G
2
Posts: 13
Reputation: 1,576


Return to Closed bugs

Who is online

Users browsing this forum: No registered users and 0 guests