getkeys() function unusual behavior when Dictionary has one key.

Martin Olavarria's icon

I started getting some weird behavior in a Javascript patch. After some testing realized that when Dict has only one item getkeys() returns a string, when Dict has more than one item getkeys() returns an array with the key names as strings.

var index = dict.getkeys();
index.length //Returns size of string when dict has only one key.


Feels like getkeys() should always return the same data type to get consistent behavior. Wanted to point this out if some else is getting the same issue.

Console shows string "data_1" when dictionary has only one key, but ["data_1", "data_2"] when dictionary has two keys.

philip meyer's icon

i have found this same issue as well and agree that getkeys() should always return an array. I don't expect to have dictionaries with solitary keys, but it can happen!

the solution i found is:

var keys = dict.getkeys();
    if(typeof keys =="string") {
        keysArr = [keys]
    } else {
        keysArr = keys
    };

broc's icon

I have noticed a similar issue with the 'get' message, in particular if the values are dicts. 'get' outputs a different format of unique name if dict is the only value or element of an array.

Max Patch
Copy patch and select New From Clipboard in Max.

Martin Olavarria's icon

Thank you for that nice work-around @Philip
I noticed this problem when trying to build a JSON configuration file for my patch, when building from scratch stuff broke right away haha.

szfpro's icon

THIS NEEDS TO BE FIXED! Thanks for solution

broc's icon

@SZFPRO
Can you explain which solution you would expect? A dictionary can have a single or multiple keys. Equally, a key can have a single or multiple values. So should all single items be represented as array with one element?

szfpro's icon

Broc,

YES!! Im not sure what the benefit is otherwise....

If a Dictionary has a Two items... dictkeys() will return 2 items in an array! (dictkeys().length == 2)
If I delete one of those keys.... dictkeys() will return 1 string! (dictkeys().length == "length of key name");

Phillips solution saved me.

Extra Note:
Across the board max is a phenomenal phenomenal tool with a HUGE but behind it.......... it simply is not intuitive for programmers which is simply bogus! A lot of cross-platform frameworks continue to come out and we're stuck in 1980s. For every solution max offers it creates itself obstacles that get in its own way. It needs to change. I would switch away from max if I had not invested years into my project. Bittersweet.

Its not enough to fix the keys function but it would be nice (y)

broc's icon

Notice that the problem doesn't occur in plain Max since a single value is automatically considered as 1-element list. But in object-oriented languages like JS type differentiation (as Philip has shown) is usually required.

szfpro's icon

I get it but, it should be easier for the programmer. Considering it IS programmed in an object oriented language. Or at least mention it in the help file. X_x

Luigi Castelli's icon

The [dict] object is very buggy whether you use it from Javascript or plain Max. It may even become unusable in certain situations.
Please take 1 min to check out this simple patch and tell me otherwise...

dict_bugs.maxpat
Max Patch

broc's icon

As I understand it, 'getsize' returns the number of associated values. So for the first 3 messages it correctly returns 1 since each key is associated with one dictionary (regardless of its content).

For the other 3 (invalid) messages I can confirm the crashing.
So apparently the error handling doesn't work as it should.

Luigi Castelli's icon

@broc: thanks for checking.
I see what you are saying with the 'getsize' message.
I stand corrected. The first three messages return indeed the correct value.