JS: Handle with find() property undefined
Asked Answered
W

2

10

I have a method which returns a value from an element in the array. Not all the elements have the property I want to return. I would like to do this function with one line using the method find(). I've tried this way to solve it:

getExecsFromTour(tourId){
 return this.repInfo.find(el => el.id == tourId ).execs || [];
}

But the elements which don't contain the property execs return an error of undefined.

To solve it, I had to store the result in a local variable:

getExecsFromTour(tourId){
    let items       = this.repInfo.find(el => el.id == tourId);
    return items    != undefined ? items.execs : [];
}

But I would like to know if I am missing something and this function can be achieved with one sentence.

Wiredraw answered 18/9, 2018 at 15:14 Comment(3)
If you really need this to be one line, you can use (this.repInfo.find(el => el.id == tourId) || {}).execs || [];Jimmiejimmy
There is no harm in making things readable on multiple lines....Jehiah
Hello! Thanks @Titus, I totally forgot the {}statment >.<. @Jehiah You're right, but I was curious about how to solve this, because it might help me in the future!Wiredraw
P
14

You seem to have the general idea, Array.prototype.find will search the array for the first element which, when used as an argument of the callback, will have the callback return a truthy value. If nothing is found, it returns undefined.

Your code should work, but yes, one way to do it in one line (if you want) is to use:

getExecsFromTour(tourId){
  return (this.repInfo.find(el => el.id == tourId) || {}).execs || [];
}

If Array.prototype.find returns undefined, the first inner parenthetical expression will be evaluated to empty object, which can attempt (and fail) to access the .execs key without a TypeError, which will also evaluate to undefined, in which case the function returns empty array, which is what your code above does.

EDIT: Someone commented this solution already, lol, but as the comments say, nothing wrong with keeping it multiline (more readable that way).

Pinkster answered 18/9, 2018 at 15:32 Comment(1)
Hello! Yes, somebody before answer this, but none with your explication. Thank you so much!Wiredraw
S
-1

what about

getExecsFromTour(tourId){
     return this.repInfo.find(el => 'execs' in el && el.id == tourId ).execs || [];
}

...

EDITED

var a = [{execs : 1, id:4}, {id:5}];
function getExecsFromTour(tourId, x){
    return (x = a.find(el => 'execs' in el && el.id == tourId )) ? x.execs : [];
}

this time at least I ran it couple of times

Spectatress answered 18/9, 2018 at 15:22 Comment(2)
No downvote from me, but I can give you another one if you want.Jehiah
The answer is wrong.... [{id:'foo', execs:[]}].find(el => 'execs' in el && el.id == 'bar' ).execs It still going to throw the same error.Jehiah

© 2022 - 2024 — McMap. All rights reserved.