Detecting an empty [] as a parameter to a function.

8 views
Skip to first unread message

Richard Quadling

unread,
Feb 24, 2009, 8:43:38 AM2/24/09
to prototype-s...@googlegroups.com
Hi.

I'm using JSONP to pass data from the server to the client.

Normally the call is like ...

tabRA_UpdateReportIDs({"13":"Richard Quadling's demo report (Richard's
complicated report)"});

A hash.

In some instances, there is no data and the call looks like this ...

tabRA_UpdateReportIDs([]);

An array.

As I understand things, this is not incorrect. I'm using PHP and I've
placed a request to allow for an option to force empty arrays to be an
empty hash for the json_encode() function. On the json_decode()
function, there is an option allowing the user to decide between an
object or an associative array (object or hash), so having a similar
option on the json_encode() side would, on the surface, seem useful.
(http://bugs.php.net/bug.php?id=47493)


My point in contacting this group is to see if ...

$H([])

should work like ...

$H({})

If you run these commands in console you get quite different output ...

$H({}).each(function(h){console.debug(h);});

vs ..

$H([]).each(function(h){console.debug(h);});

Regards,

Richard Quadling.

--
-----
Richard Quadling
Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498&r=213474731
"Standing on the shoulders of some very clever giants!"

david

unread,
Feb 24, 2009, 1:32:55 PM2/24/09
to Prototype & script.aculo.us
Hi richard,

very interresting ... and I do some test to understand results.
first, prototype method to create the Hash rely on the for..in loop.

So what is the result using the for in loop to retrieve all
properties:
I does this:

var _o={};
var _a=[];

console.log('Object definition
----------------------------------------------------');
for (var key in _o) {
console.log(key);
}
console.log('Array definition
----------------------------------------------------');
for (var key in _a) {
console.log(key);
}


and the first loop does not return anything (like your test), but the
second one return the same result of your test.

Next I try to see in Firebug, how it see those two variables:
_o is an object with no method, and _a is an array with all listed
methods.

==> So every method see the same result :))

Now the prototype doc show difference about Array and Object:
for array: "Prototype extends all native Javascript arrays with quite
a few powerful methods."
for object: "Object is used by Prototype as a namespace; that is, it
just keeps a few new methods together, which are intended for
namespaced access"

does that really means that they are treated differently ??

What does return the for in loop:
for object, nothing as it is an empty object (and native method are
not enumerate)
For Array, it's the same, the native method are not enumerate, because
you don't see the LENGTH method in the result, but the result just
show just prototype extension to the array.

I hope my though are clear enough, because I'm definitelly not sure of
my conclusion.

--
david

kangax

unread,
Feb 25, 2009, 12:49:31 AM2/25/09
to Prototype & script.aculo.us
`$H([])` produces something that it was never intended to produce - an
object extended with Array.prototype.* methods. You probably don't
ever want to use it.

--
kangax

Manfred Knops

unread,
Feb 25, 2009, 3:05:40 AM2/25/09
to prototype-s...@googlegroups.com
Guten Morgen Thomas,

hab da was fuer Dich.
Ist fuer Dich bestimmt von Interesse.
http://www.heise.de/newsticker/Webbrowser-ohne-Installation-testen--/meldung/133454

MfG
Manfred

SWilk

unread,
Feb 25, 2009, 3:27:46 AM2/25/09
to prototype-s...@googlegroups.com

It's not that Richard does want to use it. It's that the PHP
json_encode() function produces inconsistent output for empty arrays.

If you do
json_encode(array('key' => 'value');
you will get:
{ key: value };
but
json_encode(array());
returns:
[];

So it is possible, that the PHP backend returns unexpectedly empty
array instead of object. The problem clearly is on the PHP side, and
Richard propsed a patch for this issue.

Anyway, until this is fixed, and until PHP is updated on the servers
used by prototype users, a workaround is *needed*.

I think we should propose a pattern which would be used to avoid this
behaviour.
Do you have an idea how to reliably avoid that?

I think in most cases:
var _a=[];
_a = (Object.isArray(_a) && !_a.length) ? {} : _a;
var hash = $H(_a);

...would be sufficient, as not empty arrays should not be passed to
$H(). What do you think?

--
Regards,
SWilk

Richard Quadling

unread,
Feb 25, 2009, 5:27:47 AM2/25/09
to prototype-s...@googlegroups.com
2009/2/25 SWilk <wilko...@gmail.com>:
The JS workaround is fine for me. I don't have any ability to force
the patch in PHP, so from my POV, fixing the client side code is my
only option.

Admittedly, this is an edge case, so if prototype doesn't take this on
board directly, can I recommend adding a note or something to the
documentation to cover this issue. The JS workaround that has been
suggested should also be present.

Regards,

Richard.

kangax

unread,
Feb 25, 2009, 8:57:44 AM2/25/09
to Prototype & script.aculo.us
On Feb 25, 3:27 am, SWilk <wilkola...@gmail.com> wrote:
[...]
> It's not that Richard does want to use it. It's that the PHP
> json_encode() function produces inconsistent output for empty arrays.
>
> If you do
> json_encode(array('key' => 'value');
> you will get:
> { key: value };

And I assume that `json_encode(array('a', 'b', 'c'))` returns `["a",
"b", "c"]`?

[...]

> I think in most cases:
> var _a=[];
> _a = (Object.isArray(_a) && !_a.length) ? {} : _a;
> var hash = $H(_a);

That should work, but wouldn't you want to differentiate between these
"broken" arrays (which should really be empty objects) and the actual
empty arrays (returned from json)?

--
kangax

SWilk

unread,
Feb 25, 2009, 10:26:22 AM2/25/09
to prototype-s...@googlegroups.com
kangax wrote:
> On Feb 25, 3:27 am, SWilk <wilkola...@gmail.com> wrote:
> [...]
>> It's not that Richard does want to use it. It's that the PHP
>> json_encode() function produces inconsistent output for empty arrays.
>>
>> If you do
>> json_encode(array('key' => 'value');
>> you will get:
>> { key: value };
>
> And I assume that `json_encode(array('a', 'b', 'c'))` returns `["a",
> "b", "c"]`?
That's right.

>
> [...]
>
>> I think in most cases:
>> var _a=[];
>> _a = (Object.isArray(_a) && !_a.length) ? {} : _a;
>> var hash = $H(_a);
>
> That should work, but wouldn't you want to differentiate between these
> "broken" arrays (which should really be empty objects) and the actual
> empty arrays (returned from json)?

That depends on the backend of course.
For me, this would be rarely (if ever) a problem, cause I am trying
to keep my returned types consistent.
If I return an associative array from my backend, then it should be
always associative array. And I would always expect plain Object in
json response. I this case that workaround works.
If I return numerically indexed array, then it should always be so,
and then I always expect native Array in the response. In this case I
would use $A instead of $H anyway, so no workaround is needed.

Of course there might be persons who mix those types and return array
of objects when found many, and just the object, when found one. I
have no idea how to distinguish such cases... But this would require
extra js logic anyway, so I think it would not be a problem.

I agree with Richard, that there should be a warning for php users in
the docs, and a sample snippet of js code providing a way to avoid
accidental passing of empty Array to $H.

I'll try to write some info covering this on proto-scripty.wikidot.com
tonight. It might be of some help to many.

If you have any better idea how to avoid this problem,
let us know.

Regards,
SWilk

Richard Quadling

unread,
Mar 18, 2009, 9:01:56 AM3/18/09
to prototype-s...@googlegroups.com
2009/2/25 SWilk <wilko...@gmail.com>:
PHP 5.3 has just had a mod done to force json_encode() to output an
object hash. Currently it will output an array or an object hash
depending upon the array content.

The PHP manual will be updated later on today.

http://docs.php.net/json_encode

So, my issue is fixed. It would be useful to have something documented
in the Prototype manual also. This fix in PHP will ONLY be for PHP
V5.3.0 and above. RC1 of PHP5.3.0 is coming soon.

Obviously, getting this out to the ISPs will take time (these things always do).

Richard Quadling

unread,
Mar 19, 2009, 11:59:52 AM3/19/09
to prototype-s...@googlegroups.com
2009/3/18 Richard Quadling <rqua...@googlemail.com>:
PHP manual updated. Will be live by tomorrow.
Reply all
Reply to author
Forward
0 new messages