[TS 과제 챌린지] Exchange Rate Calculator - 구현

조민호·2023년 5월 30일
0
post-custom-banner

TS스터디 팀원들과 함께 매주 주차별 과제를 진행합니다


https://github.com/bradtraversy/vanillawebprojects

  • 위의 링크에는 바닐라JS로 간단히 구현된 단일 페이지의 예시들이 있습니다
  • HTML/CSS는 기존에 작성된 예시를 그대로 사용하지만, JS로직은 전부 삭제하고 스스로의 로직대로 완전히 새로 작성합니다
    - 이때 , 모든 기능 구현을 JS대신 TS로 직접 변환해서 작성합니다


4주차 - Exchange Rate Calculator

기능 동작 예시 링크 : https://vanillawebprojects.com/projects/exchange-rate/


구현 코드

const firstCurrency = document.getElementById('currency-one') as HTMLSelectElement;
const secondCurrency = document.getElementById('currency-two') as HTMLSelectElement;
const firstMoneyInput = document.getElementById('amount-one') as HTMLInputElement;
const secondMoneyInput = document.getElementById('amount-two') as HTMLInputElement;

type currencyType = {
  [key: string]: number;
};

const rateDisplay = document.getElementById('rate') as HTMLDivElement;
const swapButton = document.getElementById('swap') as HTMLButtonElement;

const getRate = async (): Promise<number> => {
  const result:currencyType = await fetch('https://open.exchangerate-api.com/v6/latest')
    .then((res) => res.json())
    .then((res) => res.rates);

  const currencyRate: number = result[secondCurrency.value] / result[firstCurrency.value];
  return currencyRate;
};

const changeRateDisplay = (rate: number) => {
  rateDisplay.innerText = `1 ${firstCurrency.value} = ${rate.toFixed(5)} ${secondCurrency.value}`;
};

const changeInputValue = (rate: number) => {
  secondMoneyInput.value = (Number(firstMoneyInput.value) * rate).toFixed(2);
};

const activate = async () => {
  const rate: number = await getRate();
  changeRateDisplay(rate);
  changeInputValue(rate);
};

const swap = () => {
  [firstCurrency.value, secondCurrency.value] = [secondCurrency.value,firstCurrency.value];
  activate();
};

firstCurrency.addEventListener('change', activate);
firstMoneyInput.addEventListener('input', activate);
secondCurrency.addEventListener('change', activate);
secondMoneyInput.addEventListener('input', activate);
swapButton.addEventListener('click', swap);
activate();

이번 구현은 최대한 각 함수는 하나의 기능만 수행하며

비동기로 API를 호출해서 먼저 환율정보를 받아온 다음에 각 로직을 진행합니다


환율 정보를 가져오는 함수입니다

    const getRate = async (): Promise<number> => {
      const result:currencyType = await fetch('https://open.exchangerate-api.com/v6/latest')
        .then((res) => res.json())
        .then((res) => res.rates);
    
      const currencyRate: number = result[secondCurrency.value] / result[firstCurrency.value];
      return currencyRate;
    };

전체 로직을 진행하는 함수입니다 환율정보를 받아와서 각 로직을 진행합니다

    const activate = async () => {
      const rate: number = await getRate();
      changeRateDisplay(rate);
      changeInputValue(rate);
    };

선택된 화폐단위를 기준으로 환율 정보를 업데이트 하며 입력된 금액을 계산해주는 함수입니다

    const changeRateDisplay = (rate: number) => {
      rateDisplay.innerText = `1 ${firstCurrency.value} = ${rate.toFixed(5)} ${secondCurrency.value}`;
    };
    
    const changeInputValue = (rate: number) => {
      secondMoneyInput.value = (Number(firstMoneyInput.value) * rate).toFixed(2);
    };

선택된 화폐단위를 바꿔주는 함수입니다
화폐단위를 바꿔주고 환율 정보과 금액을 다시 업데이트 해야 하기때문에 activate() 를 호출해 줍니다

    const swap = () => {
      [firstCurrency.value, secondCurrency.value] = [secondCurrency.value,firstCurrency.value];
      activate();
    };

어떻게든 기능별로 함수를 나누려고 했지만 코드를 작성하고 보니
이벤트가 발생할 때마다 api를 호출하는( getRate() ) , 상당히 비효율적인 로직이 되어 버렸습니다
이 부분 또한 나중에 리팩토링이 필요해 보입니다

post-custom-banner

0개의 댓글