trshmanx
trshmanx

Reputation: 680

How to write this statement without if/else?

So my company is moving to this hyper functional programming forbidding if/else and nested ternary. The function is this:

const getUrlData = (url) => {
        if (!url) {
            return { finUrl: url, newTab: false };
        } else {
            if (url.startsWith("~")) {
                return { finUrl: url.substring(1), newTab: true };
            } else {
                return { finUrl: url, newTab: false };
            }
        }
    };

How could I do this same without if's/elses and nested ternary so the code doesn't look like #@$%@@? For now it's a puzzle for me, I can't solve.

Upvotes: 0

Views: 99

Answers (5)

Cat
Cat

Reputation: 4246

You can do it with a single conditional operator (and you can use ?. to make it slightly shorter.)

const getUrlData = (url) => {
  return (url && url.startsWith("~")) // or just `url?.startsWith("~")`
    ? { finUrl: url.substring(1), newTab: true }
    : { finUrl: url, newTab: false };
};

Upvotes: 1

Sebastian Speitel
Sebastian Speitel

Reputation: 7346

Using optional chaining you can rid of any condition, but you will have to transpile it somewhere to get browser support.

const getUrlData = (url) => ({
  finUrl: url?.replace(/^~/, ''),
  newTab: !!url?.startsWith("~")
})

Transpiles to:

const getUrlData = (url) => ({
    finUrl: url === null || url === void 0 ? void 0 : url.replace(/^~/, ''),
    newTab: !!(url === null || url === void 0 ? void 0 : url.startsWith("~"))
});

console.log(getUrlData(undefined))
console.log(getUrlData('foo'))
console.log(getUrlData('~bar'))

Upvotes: 2

phuzi
phuzi

Reputation: 13059

First, lets simplify the code by inverting the if and realising that 2 of the paths through return the same response:

const getUrlData = (url) => {
    if (url && url.startsWith("~")) {
        return { finUrl: url.substring(1), newTab: true };
    }
    return { finUrl: url, newTab: false };
};

It's now obvious how to use just a single ternary expression:

const getUrlData = (url) => (url && url.startsWith("~"))
                   ? { finUrl: url.substring(1), newTab: true }
                   : { finUrl: url, newTab: false };

Upvotes: 2

Divya Sakariya
Divya Sakariya

Reputation: 507

Here is the solution for it:

const getUrlData = (url) => {
let condition = url && url.startsWith("~") ? true : false;
    return { finUrl: condition ? url.substring(1) : url, newTab: condition }
};

Upvotes: 1

thedude
thedude

Reputation: 9812

You could do something like this, splitting the function into smaller ones:

const emptyUrl = (url) => ({ finUrl: url, newTab: false })

const nonEmptyUrl = url => url.startsWith('~') ? { finUrl: url.substring(1), newTab: true } : {
  finUrl: url,
  newTab: false
}
const getUrlData = (url) => url ? nonEmptyUrl(url) : emptyUrl(url)

Upvotes: 1

Related Questions