14

How do I set a default value to a variable if array.find returns 'undefined'.

Here's the line that's causing me issues. In some instances this variable will populate but in others, it won't and in that case, I want it to default to 0.

this.statistics.creditAmount = response.data.find(t => t.paymentType == 'RF' && t.status == 1).amount || 0;
4
  • 3
    You could do this: (response.data.find(t => t.paymentType == 'RF' && t.status == 1) || { amount : 0 }).amount. But an if-else or a ternary operator check is much more readable IMO Commented Mar 26, 2019 at 19:44
  • 1
    No point in creating a snippet that can't run. Commented Mar 26, 2019 at 19:44
  • That worked like a charm @adiga although it's not very readable. What are the double pipes doing exactly? Commented Mar 26, 2019 at 19:51
  • 1
    (data.find(t => t.paymentType == 'RF' && t.status == 1) || { amount : 0 }) block first checks if there is value in the found object. If it is undefined, the OR operator will use the second object { amount : 0 }. Then get the amount property from the object returned. Commented Mar 26, 2019 at 19:58

4 Answers 4

11

I see this has been answered but I thought this could contribute

const { amount = 0 } = response.data.find(t => t.paymentType === 'RF' && t.status === 1) || {};
this.statistics.creditAmount = amount;

Or you could use a reducer:

  this.statistics.creditAmount = response.data.reduce((amt, t) => t.paymentType === 'RF' && t.status === 1 ? t.amount : amt, 0);

The reducer would use more clock cycles as it traverses the entire array, whereas Array.prototype.find stops once it reaches the first match. This may cause the results to vary as well, since the way that reducer is written it will take the last item from the array that matches.

Sign up to request clarification or add additional context in comments.

Comments

7

The problem with your code is that you're accessing .amount of undefined for cases where array.find returns undefined. You can solve it by adding a guard:

const credit = response.data.find(t => 
  t.paymentType == 'RF' && t.status == 1);

this.statistics.creditAmount = credit ? credit.amount : 0;

Comments

1

Another approach is to use a closure and a destructuring with a default object/value.

const
    getAmount = ({ amount = 0 } = {}) => amount,
    credit = getAmount(response.data.find(t => t.paymentType == 'RF' && t.status == 1));

Comments

0

Possible overkill, but you could create and implement a reusable null propagation method.

const response = {data: []};

const _try = (func, fallbackValue) => {
    try {
        var value = func();
        return (value === null || value === undefined) ? fallbackValue : value;
    } catch (e) {
        return fallbackValue;
    }
}


const result = _try(() => response.data.find(t => t.paymentType == 'RF' && t.status == 1).amount, 0);
console.log(result);

This was originally written by tocqueville as part of this answer.

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.