0

I wonder if there is a method to exit function based on other function output.

In other words: I have a function that evaluates some values and if they are fine returns them, otherwise causes a warning to user.

 const verifier = () => {
                const a = Number(document.querySelector("#a").value);
                const b = Number(document.querySelector("#b").value);

                if(isNaN(a) || isNaN(b)) {
                    console.log("Sent notification to user");    
                    return
                }
                return [a, b]
            }

Now, I use it multiple times, e.g.:

            const adder = () => {
                const [a,b] = verifier() || return; // <--- HERE!
                console.log(a);
                console.log(b);
            }

In HERE: if verification function returns false / undefined / null I would like to exit my function prematurely, otherwise: assign to variables.

  • Just a side note: `Number(document.querySelector("#a").value)` will give you `0` if the value is `""`, which you may or may not want. I go through your various options for converting from string to number with their pros and cons in [this answer](https://stackoverflow.com/questions/28994839/why-does-string-to-number-comparison-work-in-javascript/28994875#28994875). – T.J. Crowder Mar 23 '21 at 13:10
  • You could use a helper function (for example `ifVerified`) that accepts a callback and only calls it on verified results. `adder` could then become: `const adder = () => ifVerified(([a, b]) => { /* ... */ });` (or similar) – Yoshi Mar 23 '21 at 13:17
  • 1
    @T.J.Crowder, I know, this functions are truncated to show the concept :p But thanks for notification anyway :-) – Vardens Archangel Mar 23 '21 at 19:41

2 Answers2

2

As I wrote in my comment, if you're willing to introduce an intermediary helper, you could write it as follows:

const verifier = () => {
  const a = Number(document.querySelector("#a").value);
  const b = Number(document.querySelector("#b").value);

  if(isNaN(a) || isNaN(b)) {
    console.log("Sent notification to user");
    return;
  }

  return [a, b];
}

// helper that only calls `fn` if verifier does not return undefined
const ifVerified = (fn) => {
  const values = verifier();

  return undefined === values ? undefined : fn(values);
};

const adder = () => ifVerified(([a, b]) => {
  // do something with a and b
});
Yoshi
  • 54,081
  • 14
  • 89
  • 103
  • Yeah, there are a dozen ways to skin this cat. :-) (BTW: You either don't want spread when calling `fn`, or you want to define your callback to `ifVerified` at the end differently.) – T.J. Crowder Mar 23 '21 at 13:27
1

You can't use return where an expression is expected, because return is a statement.

There are a bunch of other ways to do it, but they're all going to be clunkier than you're going to want. :-) For instance, you could have verifier return the NaN values and then test the result:

const verifier = () => {
    const a = Number(document.querySelector("#a").value);
    const b = Number(document.querySelector("#b").value);

    if (isNaN(a) || isNaN(b)) {
        console.log("Sent notification to user");    
        return [NaN, NaN];
    }
    return [a, b];
};
const adder = () => {
    const [a,b] = verifier();
    if (isNaN(a)) {
        return;
    }
    console.log(a);
    console.log(b);
};

Or you could leave verifier as it is and use nullish coalescing (quite new) at the point where you call it:

const adder = () => {
    const [a, b] = verifier() ?? [];
    if (a === undefined) {
        return;
    }
    console.log(a);
    console.log(b);
};

perhaps with an explicit flag value as a default:

const adder = () => {
    const [a = null, b] = verifier() ?? [];
    if (a === null) {
        return;
    }
    console.log(a);
    console.log(b);
};

Or store the returned array/undefined and test that:

const adder = () => {
    const result = verifier();
    if (!result) {
        return;
    }
    const [a, b] = result;
    console.log(a);
    console.log(b);
};

But they all involve that if. (Or you could throw.)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875