Reuben
Reuben

Reputation: 141

Writing if/else statements with 3 conditions with a promise mixed in

So I have this conditional statement with 2 conditions, whereby

let modItemList = this.props.items

    if (this.state.searchItemName) {   // condition1
        modItemList = (
            this.props.items.filter(
                (item) => item.name.toLowerCase().indexOf(lcName) !== -1    // For name
            )
        );
    } else if (this.state.searchItemAddress) {    //condition2
        modItemList = (
            this.props.items.filter(
                (item) => item.fullAddress.some(e => e.toLowerCase().indexOf(lcAddress) !== -1)      // For Address
            )
        );
    } 

This is where it's a little tricky to explain.

Now I want to add a 3rd condition, which happens only if both condition1 and condition2 are met, AND the outcome is that of executing code from condition1 and condition2.

How would I go about expressing that?

Upvotes: 0

Views: 282

Answers (4)

T.J. Crowder
T.J. Crowder

Reputation: 1074168

There's no asynchronous action here, so no need to track an async action with a promise.

Probably the simplest thing is to filter the filtered list:

let modItemList = this.props.items;
if (this.state.searchItemName) {
    modItemList = modItemList.filter(item => item.name.toLowerCase().includes(lcName));
}
if (this.state.searchItemAddress) {
    modItemList = modItemList.filter(item => item.fullAddress.some(e => e.toLowerCase().includes(lcAddress)));
}

Or filter once and check for searchItemName and searchItemAddress within the callback:

let modItemList = this.props.items.filter(item =>
    (!this.state.searchItemName    || item.name.toLowerCase().includes(lcName)) &&
    (!this.state.searchItemAddress || item.fullAddress.some(e => e.toLowerCase().includes(lcAddress));

Even if the list is in the hundreds of thousands of entries, neither of those is going to be slow enough to worry about.

Or if it really bothers you do do that double-filtering or re-checking, build a filter function:

let modItemList;
let filterFunc = null;
if (this.state.searchItemName && this.state.searchItemAddress) {
    filterFunc = item => item.name.toLowerCase().includes(lcName) && item.fullAddress.some(e => e.toLowerCase().includes(lcAddress));
} else if (this.state.searchItemName) {
    filterFunc = item => item.name.toLowerCase().includes(lcName);
} else if (this.state.searchItemAddress) {
    filterFunc = item => item.fullAddress.some(e => e.toLowerCase().includes(lcAddress));
}
modItemList = filterFunc ? this.props.items.filter(filterFunc) : this.props.items;

That involves repeating yourself a bit, though, leaving open the possibility that you'll update one address filter but not the other. You can aggregate the filter functions:

let nameCheck    = item => item.name.toLowerCase().includes(lcName);
let addressCheck = item => item.fullAddress.some(e => e.toLowerCase().includes(lcAddress));
let modItemList;
if (this.state.searchItemName && this.state.searchItemAddress) {
    modItemList = this.props.items.filter(item => nameCheck(item) && addressCheck(item));
} else if (this.state.searchItemName) {
    modItemList = this.props.items.filter(nameCheck);
} else if (this.state.searchItemAddress) {
    modItemList = this.props.items.filter(addressCheck(item);
}

If there were more than two, we might look at putting them in an array and doing

modItemList = this.props.items.filter(item => arrayOfFunctions.every(f => f(item)));

So...lots of options. :-)


I've used includes(x) rather than indexOf(x) !== -1 above. I find it clearer.

Upvotes: 0

Bergi
Bergi

Reputation: 664366

I think you just want to use two separate if conditions where both may run, not if/else if:

let modItemList = this.props.items;

if (this.state.searchItemName) {   // condition1
    modItemList = modItemList.filter(item =>
        item.name.toLowerCase().indexOf(lcName) !== -1    // For name
    );
}

if (this.state.searchItemAddress) {    //condition2
    modItemList = modItemList.filter(item =>
        item.fullAddress.some(e => e.toLowerCase().indexOf(lcAddress) !== -1)      // For Address
    );
}

Nothing is asynchronous here or involves promises. If it did, I would recommend to just place an await in the respective location.

Upvotes: 2

Márius Rak
Márius Rak

Reputation: 1472

You would still need to wait with the action till promise is resolved and finished. So you would check the conditions inside of promise callback and then make adequate actions. Until you have resolved promise, you can display some "loading" information.

Upvotes: 0

Daniil Palii
Daniil Palii

Reputation: 1220

Maybe this solution You want?

if (condition1 & condition2) {
   something = this.props.something.filter(1)).then(this.props.something.filter(2)
} else if (condition1) {
   something = this.props.something.filter(1)
} else if (condition2) {
   something = this.props.something.filter(2)
}

Upvotes: -1

Related Questions