2

I am getting into the habit of, depending on the context, converting some of my for loops to use array.find(). In so doing, I'm wondering if there's a way I can chain another operator on after the .find() in order to limit how much I grab from the object.

For instance, see the following:

currentStage = customerDoc.history.find(h => h.completed === false);
currentStageName = currentStage.name;

Since all I really want from here is the value for "currentStage.name", is there a way I can get this by chaining on after my find(), to specify I just want this property? If not, is there another way to do this in one line?

3
  • .find(...).name Commented Jul 25, 2019 at 19:06
  • 2
    @epascarello As much as I agree, an exception would be thrown if find() doesn't find anything. Commented Jul 25, 2019 at 19:07
  • @zero298 just like how it would with the code above ;) Commented Jul 25, 2019 at 19:07

4 Answers 4

5

Yes you can like this, notice the use of || {} to avoid exception in case the find returns undefined

currentStage = (customerDoc.history.find(h => h.completed === false) || {}).name

But IMO you should keep it like you have right now, it's readable and easy to maintain

currentStage = customerDoc.history.find(h => h.completed === false);
currentStageName = currentStage && currentStage.name;
Sign up to request clarification or add additional context in comments.

2 Comments

Given that .find returns undefined if it can't match anything, it would be good to ensure that currentStage is not undefined. This can be as simple as currentStageName = currentStage && currentStage.name;
Thanks, and yes, that's a fair point. Sometimes clarity beats out being hyper-terse.
5

You could use optional chaining (which was introduced with ECMAScript 2020):

const currentStageName = customerDoc.history.find(h => !h.completed)?.name;

Comments

3

Use short-circuit evaluation to have a default object in case nothing if found, and destructuring to get the property you want. If nothing is found, the result would be undefined:

const { name: currentStageName } = customerDoc.history.find(h => h.completed === false) || {};

1 Comment

I like the destructuring method better because it keeps it all on one line, the disadvantage is makes for a longer and more complex line of code.
1

you could also chain a .map onto the find results in order to limit and/or reshape what gets returned by wrapping it in an array (and using filter if no results are found), e.g.

currentStage = [customerDoc.history.find(h => h.completed === false)].filter(h => h != undefined).map(h => ({'name':h.name}))[0]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.