1

What would be a better way to try checking that response is an array with length?

try{
    response.errors.length > 0;
    deferred.reject(response)
}
catch(e){
    deferred.resolve(response);
}
karthikr
  • 97,368
  • 26
  • 197
  • 188
4m1r
  • 12,234
  • 9
  • 46
  • 58
  • 1
    The length check will *not* throw an exception. What *might* is `response` or `response.errors` evaluating to undefined. – user2246674 Oct 02 '13 at 18:41
  • possible duplicate of [Checking if an associative array key exists in Javascript](http://stackoverflow.com/questions/1098040/checking-if-an-associative-array-key-exists-in-javascript) – Bergi Oct 02 '13 at 18:45
  • To be clear, I want this expression to evaluate in the context of try catch so that I can capture the exception. As per jshint: "Expected an assignment or function call and instead saw an expression." All the answers imply that I should not even be using try, which is fine. I'm just wondering how I would satisfy the jshint error. – 4m1r Oct 02 '13 at 19:45

5 Answers5

2

This will make sure that errors is an array and it has items in it.

if (Array.isArray(response.errors) && response.errors.length) {
    deferred.reject(response);
} else {
    deferred.resolve(response);
}
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • I dare say never check for if something is-an array; that's what duck typing is for ;-) The exception would be if I need to perform some kind of "overloading" based on a parameter - in which case the explicit check is more prudent. – user2246674 Oct 02 '13 at 18:48
  • @user2246674 Agreed. But this is what the OP want I believe. `checking that response is an array with length` – thefourtheye Oct 02 '13 at 18:51
  • I suppose that is a reading - although not mine :) This answer is perfectly correct in the provided context. – user2246674 Oct 02 '13 at 18:51
1

One way is:

if (response.errors.length) {
    deferred.reject(response);
} else {
    deferred.resolve(response);
}

This is using the fact that 0 is considered falsey in JavaScript, and any other number is considered truthy.

If you're worried about the type of response.errors, you can add response.errors instanceof Array to the if condition:

if (response.errors instanceof Array && response.errors.length) {
ajp15243
  • 7,704
  • 1
  • 32
  • 38
  • 1
    How do we make sure that it is an Array? Even functions can have length property. – thefourtheye Oct 02 '13 at 18:41
  • @thefourtheye Good point, this is arguably in scope for this question, edited. – ajp15243 Oct 02 '13 at 18:45
  • @thefourtheye We *don't* care if it's an array. Duck-typing. – user2246674 Oct 02 '13 at 18:47
  • @user2246674 Why don't we care? The question clearly asks specifically about arrays, there may be the need for it. No reason not to include that bit of knowledge. – ajp15243 Oct 02 '13 at 18:48
  • 1
    @ajp15243 Because it's an orthogonal topic - the meat of the question is how to handle where there may be an *optional* array, not that there is an arbitrary value which *may be* an array. – user2246674 Oct 02 '13 at 18:49
  • @user2246674 True, I figured it was a tangential topic at best, hence my keeping it separate from the core answer. – ajp15243 Oct 02 '13 at 19:13
0

The length check (length > x) will not throw an exception. What might throw an exception is if response or errors evaluates to undefined (e.g. doesn't exist).

if (response && response.errors && response.errors.length) {
  // Have errors
  // The check for response might not be needed, but one should most
  // definitely ensure that `response.errors` evaluates to an object (Array?)
  // before trying to access a property upon it.
}

Note that this uses && short-circuiting behavior.

Alternatively, sometimes it's nice to normalize data (assumes response is always an object). In this case we make sure that we have an "empty array" as needed such that we have some array on which to check the length.

response.errors = response.errors || []
if (response.errors.length) {
   // Have errors
}

In the above examples I also utilize that a non-0 number in JavaScript is a truth-y value, which allows if (length > 0) .. to be written as if (length) .. and it will work reliably assuming that length is always a number, when present.

user2246674
  • 7,621
  • 25
  • 28
0

What about

if (response.errors && response.errors.length > 0)
   deferred.reject(response);
else
    deferred.resolve(response);

No need to catch exceptions from accessing non-existent properties, just test for their existence before…

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

If you want to be explicit about checking that it is an array.

if (response.errors && (response.errors instanceof Array) && response.errors.length > 0)
   deferred.reject(response);
else
   deferred.resolve(response);

(Tested in FF and Chrome).

fred02138
  • 3,323
  • 1
  • 14
  • 17