Zoko
Zoko

Reputation: 99

How do I add functions into a JavaScript switch statement?

I'm designing a temperature converter and trying to get the conversion function to change depending on the unit selected. Fahrenheit is the default calculation and I can't seem to change it to the other conversions when the unit is switched. How can I add my conversion functions into my switch statement?

// Select unit
const units = document.querySelector('#units');

units.addEventListener('change', function(e) {  
  let selectedUnit = units.selectedIndex;
  let degree = document.querySelector('#degree');  
        
  switch(selectedUnit) {
    case 0:
    degree.innerHTML = "°F";
    document.getElementById('tag1').innerHTML = "°C";
    document.getElementById('tag2').innerHTML = "°R";
    document.getElementById('tag3').innerHTML = "°K";
    document.getElementById('fahrenheit').placeholder = "Degrees fahrenheit";
    
    break;

    case 1:
    degree.innerHTML = "°C";    
    document.getElementById('tag1').innerHTML = "K";
    document.getElementById('tag2').innerHTML = "°R";
    document.getElementById('tag3').innerHTML = "°F";
    document.getElementById('fahrenheit').placeholder = "Degrees Celsius";
    break;

    case 2:
    degree.innerHTML = "°R";    
    document.getElementById('tag1').innerHTML = "°C";
    document.getElementById('tag2').innerHTML = "K";
    document.getElementById('tag3').innerHTML = "°F";
    document.getElementById('fahrenheit').placeholder = "Degrees Rankine";
    break;

    case 3:    
    degree.innerHTML = "K";        
    document.getElementById('tag1').innerHTML = "°C";
    document.getElementById('tag2').innerHTML = "°R";
    document.getElementById('tag3').innerHTML = "°F";
    document.getElementById('fahrenheit').placeholder = "Kelvin";
    break;

    default:
    degree.innerHTML = "°F";
    document.getElementById('fahrenheit').placeholder = "Degrees Fahrenheit";
    break;
  }
});

// Listen for submit
document.querySelector('#temp-form').addEventListener('submit', function(e) {
  // Hide results
  document.querySelector('#results').style.display = 'none';

  // Show loader
  document.querySelector('#loading').style.display = 'block';

  setTimeout(calculateResults, 2000);
  
  e.preventDefault();
});

// Calculate Results
function calculateResults(e){
  console.log('Calculating...');
  // UI Vars
  const fahrenheitInput = document.querySelector('#fahrenheit');
  const celsiusInput = document.querySelector('#celsius');
  const rankineInput = document.querySelector('#rankine');
  const kelvinInput = document.querySelector('#kelvin');

  function fahrenheitConversion() {
    const ftemp = parseFloat(fahrenheitInput.value);
    const ctemp = (ftemp - 32) * (5/9);
    const rtemp = ftemp + 459.67;
    const ktemp = (ftemp - 32) * (5/9) + 273.15;
    
    celsiusInput.value = ctemp.toFixed(2);
    rankineInput.value = rtemp.toFixed(2);
    kelvinInput.value = ktemp.toFixed(2);
  }

  function celsiusConversion() {
    const ctemp = parseFloat(celsiusInput.value);
    const ftemp = (ctemp * (9/5)) + 32;
    const rtemp = (ctemp * (9/5)) + 491.67;
    const ktemp = ctemp + 273.15;
    
    fahrenheitInput.value = ftemp.toFixed(2);
    rankineInput.value = rtemp.toFixed(2);
    kelvinInput.value = ktemp.toFixed(2);
  }

  function rankineConversion() {
    const rtemp = parseFloat(rankineInput.value);
    const ctemp = (rtemp - 491.67) * (5/9);
    const ftemp = rtemp - 459.67;
    const ktemp = rtemp * (5/9);
    
    celsiusInput.value = ctemp.toFixed(2);
    fahrenheitInput.value = ftemp.toFixed(2);
    kelvinInput.value = ktemp.toFixed(2);
  }

  function kelvinConversion() {
    const ktemp = parseFloat(kelvinInput.value);
    const ctemp = ktemp - 273.15;
    const rtemp = ktemp * (9/5);
    const ftemp = (ktemp - 273.15) * (9/5) + 32;
    
    celsiusInput.value = ctemp.toFixed(2);
    rankineInput.value = rtemp.toFixed(2);
    fahrenheitInput.value = ftemp.toFixed(2);
  }
  
  // Show results
  document.querySelector('#results').style.display = 'block';

  // Hide loader
  document.querySelector('#loading').style.display = 'none';

  fahrenheitInput.addEventListener('submit', fahrenheitConversion());
  celsiusInput.addEventListener('submit', celsiusConversion());
  rankineInput.addEventListener('submit', rankineConversion());
  kelvinInput.addEventListener('submit', kelvinConversion());
}

Upvotes: 1

Views: 381

Answers (1)

Anton Krug
Anton Krug

Reputation: 1781

I think your variable is a string, but your case switch statement works on numbers. If you will struggle with code and why is doing what is doing, you can do a couple of things.

if (debug_unit_conversion) console.log(......

This way you could troubleshoot different parts/modules of code by changing a few variables.

The code itself it could be done many other ways, overall you do not want to have case switch statements to grow into huge ones, command design pattern is good to remedy that: https://www.dofactory.com/javascript/design-patterns/command or you can do something in between and have just callbacks on specific options to invoke the code.

This might be nit picking because it could be seen already as a part of view and view can have a bit of logic. But it seems to me that the business logic (controller) is partially overlapping with your presentation (view), you could split the function into two, the first would be just deciding what things to display in what order and the second one to display them. So the first one would return an array of innerHTML contents and the second one would apply this array to the HTML itself. Then for each 'unit' the second function can be reused and to some extent you should be able to modify how you are presenting things (or if you find better way to update the HTML) without having to change the logic part of what will get displayed in what order.

For example

document.getElementById('fahrenheit').placeholder = "Degrees Celsius";

can look confusing, imagine going back to this code after a few years, the best code is the one which is self-documenting and this one could confuse you. Would 'unit', 'unitDescription' or 'unitText' be more fitting?

Upvotes: 1

Related Questions