Tienus McVinger
Tienus McVinger

Reputation: 477

Is there a way to limit the need of if-conditions here?

As a follow-up to this question, I've managed to apply multiple filters to my observable, depending on which filters a user decides to apply.

The "problem" I have is that it's not certain if a filter is applied at all, and even then all filters work differently; some are numbers and others are strings.

I get my observable like so:

getProperties(): Observable<Property[]> {
    return this.http.get<Property[]>(this.url);
}

and apply my dynamic filters like so:

filterAndSort() {
    let count = 0;
    return this.getProperties()
    //Only return properties where price is higher than or equal to min price
    .map(properties => properties.filter((property) => {
        if(property.price >= this.userSettings.getAppSetting("filterMinPrice", "number")) {
            return property;
        }
    })
    .filter((property) => {
        //Return all properties if max price is not set (0)
        if(this.userSettings.getAppSetting("filterMaxPrice", "number") == 0) {
            return property;
        }
        //Only return properties where price is lower than or equal to max price
        else if(property.price <= this.userSettings.getAppSetting("filterMaxPrice", "number")) {
            return property;
        }
    })
    .filter((property) => {
        if(property.incomeCategory == this.userSettings.getAppSetting("filterIncomeClass", "string")) {
            return property;
        } else if (this.userSettings.getAppSetting("filterIncomeClass", "string") == "none") {
            return property;
        }
    })
    .filter((property) => {
        if(property.numberOfRooms >= this.userSettings.getAppSetting("filterMinRooms", "number")) {
            return property;
        }
    })
    .filter((property) => {
        if(property.numberOfBedrooms >= this.userSettings.getAppSetting("filterMinBedrooms", "number")) {
            return property;
        }
    })
    .sort((a: Property, b: Property) => {
        //..
        }
    ))
}

It works, but I think it's not the best solution as I'm calling filter() over and over again. I think that if I somehow manage to reduce the excessive amount of if-conditions and only use return property; once within that condition, my code will be a whole lot neater. (keep in mind that I will add even more filter options in the future, so this is bound to get even messier if I have to apply them in a similar way :p)

Any suggestions?

(Just to clear things up: I'm using NativeScript/Angular/Typescript here).

Upvotes: 1

Views: 72

Answers (1)

shaunhusain
shaunhusain

Reputation: 19748

This might work I'm not sure if it can be considered an improvement but just trying to condense the results of the logic into one filter function:

.filter(property => {
      if(
        (
          this.userSettings.getAppSetting("filterMaxPrice", "number") == 0 ||
          property.price <= this.userSettings.getAppSetting("filterMaxPrice", "number")
        ) &&
        (
          property.incomeCategory == this.userSettings.getAppSetting("filterIncomeClass", "string") ||
          this.userSettings.getAppSetting("filterIncomeClass", "string") == "none"
        ) &&
        (
          property.numberOfRooms >= this.userSettings.getAppSetting("filterMinRooms", "number")
        ) &&
        (
          property.numberOfBedrooms >= this.userSettings.getAppSetting("filterMinBedrooms", "number")
        )
      ) {
          return property;
      }
  })

Upvotes: 2

Related Questions