Build a Currency Converter - Build a Currency Converter

Tell us what’s happening:

Hi all

My code fails on test 7 and 8

I can get test 7 to pass by changing the initial start value of my amount state to 1 instead of 0, but I cant understand why this would make a difference to that particular test

For test 8 , I can see the amounts changing when the second select value is changed but the test fails.

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>Currency Converter</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.development.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.development.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.26.5/babel.min.js"></script>
    <script
      data-plugins="transform-modules-umd"
      type="text/babel"
      src="index.jsx"
    ></script>
    <link rel="stylesheet" href="styles.css" />
</head>

<body>
    <div id="root"></div>
    <script
      data-plugins="transform-modules-umd"
      type="text/babel"
      data-presets="react"
      data-type="module"
    >
      import { CurrencyConverter } from './index.jsx';
      ReactDOM.createRoot(document.getElementById('root')).render(<CurrencyConverter />);
    </script>
</body>

</html>
/* file: index.jsx */
const { useState, useMemo } = React;

const EXCHANGERATEOBJ = {
    USD: 1,
    EUR: 0.92,
    GBP: 0.78,
    JPY: 156.70,
}

export function CurrencyConverter() {
  const [amount, setAmount] = useState(0)
  const [exchangeFrom, setExchangeFrom] = useState('USD')
  const [exchangeTo, setExchangeTo] = useState('EUR')
  
  // Map over the currency list for option elements
  const currencyOptions = () => {
    return Object.keys(EXCHANGERATEOBJ).map((c, i) => <option key={c + i}>{c}</option>)
  }

  // Use useMemo to memoization conversion objects
  const convertedAmounts = useMemo(() => {
    const convertedAmountsObj = {}

    for(const key in EXCHANGERATEOBJ) {
      convertedAmountsObj[key] = (amount * (EXCHANGERATEOBJ[key] / EXCHANGERATEOBJ[exchangeFrom])).toFixed(2)
    }
    return convertedAmountsObj
  }, [amount, exchangeFrom]) 
    
  return (
    <form>

      <h1>Currency Converter</h1>

      <label htmlFor="input-amount">Amount</label>
      <input id="input-amount" type="number" min="0" step="1.00" placeholder="0.00" onChange={(e)=>setAmount(e.target.value)} name="inputAmount" value={amount}/>

      <label htmlFor="exchange-from">From</label>
      <select id="exchange-from" onChange={(e)=>setExchangeFrom(e.target.value)}>
        {currencyOptions()}
      </select>

      <label htmlFor="exchange-to">To</label>
      <select id="exchange-to" onChange={(e)=>setExchangeTo(e.target.value)}>
        {currencyOptions()}
      </select>

      <h2>Converted Amount: {convertedAmounts[exchangeTo]} {exchangeTo}</h2>

    </form>
  )
}
/* file: styles.css */
body {
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-color: grey;
}

form {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: white;
  background-color: black;
  padding: 50px;
}
label {
  padding-top: 12px;
  padding-bottom: 8px
}

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36

Challenge Information:

Build a Currency Converter - Build a Currency Converter

const { useState, useMemo } = React;

const EXCHANGERATEOBJ = {
    USD: 1,
    EUR: 0.92,
    GBP: 0.78,
    JPY: 156.70,
}

export function CurrencyConverter() {
  const [amount, setAmount] = useState(1)
  const [exchangeFrom, setExchangeFrom] = useState('USD')
  const [exchangeTo, setExchangeTo] = useState('EUR')
  
  // Map over the currency list for option elements
  const currencyOptions = () => {
    return Object.keys(EXCHANGERATEOBJ).map((c, i) => <option key={c + i} value={c}>{c}</option>)
  }

  // Use useMemo to memoization conversion objects
  const convertedAmounts = useMemo(() => {
    const convertedAmountsObj = {}

    for(const key in EXCHANGERATEOBJ) {
      convertedAmountsObj[key] = (amount * (EXCHANGERATEOBJ[key] / EXCHANGERATEOBJ[exchangeFrom])).toFixed(2)
    }

    return convertedAmountsObj
  }, [amount, exchangeFrom]) 
    
  return (
    <form>

      <h1>Currency Converter</h1>

      <label htmlFor="input-amount">Amount</label>
      <input id="input-amount" type="number" min="0" step="1.00" placeholder="0.00" onChange={(e)=>setAmount(e.target.value)}/>

      <label htmlFor="exchange-from">From</label>
      <select id="exchange-from" onChange={(e)=>setExchangeFrom(e.target.value)} value={exchangeFrom}>
        {currencyOptions()}
      </select>

      <label htmlFor="exchange-to">To</label>
      <select id="exchange-to" onChange={(e)=>setExchangeTo(e.target.value)} value={exchangeTo}>
        {currencyOptions()}
      </select>

      <h2>Converted Amount: {convertedAmounts[exchangeTo]} {exchangeTo}</h2>

    </form>
  )
}

all tests now pass but i still dont understand what difference the initial start value makes, to those two tests

This is actually a test issue rather than a problem with your code logic.

Tests 7 and 8 work by capturing the converted amount displayed before changing a select, then changing the select, and checking that the displayed amount is different afterwards. The problem is that the tests never set the input to a non-zero value before running — they rely on whatever initial state you gave to amount.

If your initial amount state is 0, any conversion will display 0.00 regardless of which currency is selected. So when the test changes the from-currency, the displayed value is still 0.00 — unchanged — and the test fails.

Setting the initial amount to 1 (or any non-zero value) makes the tests pass because changing the currency actually produces a different number.

This is a limitation of these tests — the requirement for a non-zero initial amount is implicit and not stated in the user stories. I have opened an issue to track the fix: Build a Currency Converter: tests 7 and 8 implicitly require non-zero initial amount · Issue #66396 · freeCodeCamp/freeCodeCamp · GitHub

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.