jquery: $.each breaks on string

Description

When calling $.each with jQuery 3.3.1 like so:

$.each("woohoo");

What actually happens

It breaks with an error:

Uncaught TypeError: Cannot use 'in' operator to search for 'length' in woohoo

What I expect to happen instead

I think it should do either one of two things:

  1. Loop through the string character by character.
  2. Output a more sensible error, something like “incorrect parameter type string for jQuery.each”

Browsers affected

  • Firefox and Chrome throw the error above
  • Edge throws a different error Invalid operand to 'in': Object expected which means the same.
  • Safari throws another different error TypeError: obj is not an Object. (evaluating '"length" in obj') which means the same again.

I suspect this problem affects every browser.

Link to test case

https://jsfiddle.net/botp2fuL/1/

Use-case

I was each-ing through an object that is expected to sit in a data attribute on an element. Somehow, because of undue circumstances let’s say, that data attibute is no longer rendered by the server as valid json, and is therefor passed to my code as a string, throwing the error I describe here.

Novice developers might ignore this error for too long, because it doesn’t look like an error in their code. This is no excuse, but I do believe clear error messages, or expectable behaviour when doing this on purpose, helps everyone.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 23 (11 by maintainers)

Most upvoted comments

@dmethvin Do we need a similar note on https://api.jquery.com/Types/#Object & https://api.jquery.com/Types/#PlainObject?

BTW, https://api.jquery.com/Types/#Object says “Everything in JavaScript is an object”, an interesting twist in this discussion. 😆

This is not just jQuery.each problem. There are lots of APIs that may behave unexpectedly or just blow up if you provide incorrect input to them. Making them all fail with helpful error messages would increase the library size significantly, especially that some of jQuery’s signatures are really dynamic and accept various parameter tuples.

As I said, TypeScript or Flow are your friends if you want to catch this type of errors earlier. Maybe there are some community linters that would catch it, I’m not sure. Whatever happens, we just don’t want to send such code to end-users, it should be contained in developers’ machines. I don’t think we’ll be able to work on anything like that in the foreseeable future.