JC_Rambo
JC_Rambo

Reputation: 61

What's the best way to avoid many if statements in Angular component to call specific function?

I'm creating a temperature conversion app in Angular 7, in my formGroup I have an input/output value, and 2 multi selects where the user can select a unit of temperature 'From' and 'To' to convert(celsius, Fahrenheit or Kelvin).

When the user submit the form in my component I get the input data

submitForm(data) {
    this.input = data.input;
    this.unitInput= data.unitInput;
    this.unitTarget= data.unitTarget;
    this.output= data.output;
  }

I thought in just adding if statements to call the function that will make the conversion, but now looking at all if statements that i have seems a lot and not a good design.

if (this.inputUnit === 'Celsius' && this.targetUnit === 'Fahrenheit') {
        this.celsiusToFahrenheitConversion ();
}
if (this.inputUnit === 'Celsius' && this.targetUnit === 'Kelvin') {
      this.celsiusToKelvinConversion ();
}
if (this.inputUnit === 'Celsius' && this.targetUnit === 'Rankine') {
      this.celsiusToRankineConversion ();
}

If's for Fahrenheit, If's for Kelvin, If's for Rankine, etc.. and what about if in the feature I want to add a different kind of unit? What would be a better approach?

Thanks in advance

Upvotes: 1

Views: 245

Answers (2)

Jamie Dixon
Jamie Dixon

Reputation: 53991

When I look at this I see compound keys set against a function value.

One way to represent this idea is with an typical object where the keys are the compound and they map to a specific function:

const conversionFunctions = {
    'celsius-fahrenheit': this.celsiusToFahrenheitConversion,
    'celsius-kelvin': this.celsiusToKelvinConversion,
    'celsius-rankine': this.celsiusToRankineConversion
};

const key = `${this.inputUnit.toLowerCase()}-${this.targetUnit.toLowerCase()}`;
const convert = conversionFunctions[key];

convert();

Upvotes: 0

Jiri Kralovec
Jiri Kralovec

Reputation: 1617

I think the cleanest way to handle this would be using a switch statement. It doesn't get simpler than that, I personally hate it as well but sometimes there is just no way around it really.

switch(this.inputType) {
  case 'Celsius':
    switch(this.targetUnit) {
      case 'Fahrenheit':
        this.celsiusToFahrenheitConversion();
        break;
      case 'Kelvin':
        this.celsiusToKelvinConversion();
        break;
      case 'Rankine':
        this.celsiusToRankineConversion();
        break;
    }
    break;
  case 'Fahrenheit':
    break;
  case 'Rankine':
    break;
  case 'Kelvin':
    break;
}

However! This is a mathematical conversion. F° to C° (32°F − 32) × 5/9, F° to Kelvin is (32°F − 32) × 5/9 + 273.15, F° to Rankine is 32°F + 459.67 and so on. And where is math, there is a system. My approach would be creating a conversion table - an object, and use the form values as lookup values. For example:

const magicalLookupTable = {
  celsius: {
    fahrenheit: () => {
      /** Implementation */
    },
    kelvin: () => {
      /** Implementation */
    }
  },
  fahrenheit: {
    celsius: () => {
      /** Implementation */
    },
    kelvin: () => {
      /** Implementation */
    }
  }
}

Upvotes: 3

Related Questions