[Javascript Toy Project] Exchange Rate App | 환율계산기 만들기 토이프로젝트

이은진·2020년 11월 10일
15

인터넷 강의를 따라 만든 환율 계산기의 자바스크립트 코드가 조금 가독성이 떨어져서, 재사용 및 확장에 용이한 방향으로 전반적인 코드를 개선하고 기능을 추가해보았습니다. Fetch APIAsync/Await 연습을 위해 조금 비효율적이더라도 여러 개의 API를 교차로 사용해보았습니다. 이번 프로젝트에서도 마찬가지로 UI/UX 디자인을 개선했습니다.

Contents

  1. 전체 UI/UX 소개
  2. 주요 특징들 : 완성된 환율 계산기의 주요 특징을 구현한 코드
  3. 개선한 점 : 기존 인터넷 강의 튜토리얼에서 개선된 점, 프로젝트 과정 중 겪은 시행착오 등
  4. 아쉬운 점

1. Exchange Rate App UI/UX

바닐라 자바스크립트로 만든 환율계산기는 세계환율 API에서 데이터를 가져와 실시간으로 값을 환산해주는 앱입니다. 제목을 제외하고 가장 중요한 정보인 환율의 글자 크기를 가장 크게 하였고 주요 색상을 신뢰감을 주는 파란색으로 설정했습니다. 필요한 기능만 깔끔하게 배치시켰습니다.

2. Main Features

2-1. My country's currency selected when accessed

접속한 국가를 알려주는 API를 이용해서, 환율계산기 앱에 접속한 사람이 속한 국가의 환율 정보를 디폴트로 알려주는 기능을 추가했습니다. 기본 단위를 미국 달러로, 환산한 단위를 접속한 국가의 통화 단위로 설정하였습니다.

//get your country code - KR
const getCountryCode = async () => {
  const response = await fetch('https://ipinfo.io/json?token=c76190236a0eea')
  if (response.status === 200) {
    const location = await response.json()
    return location.country
  } else {
    throw new Error('Unable to get your location')
  }
}

//get general currency code with a country code - KRW
const getCurrencyCode = async (countryCode) => {
  const response = await fetch('http://restcountries.eu/rest/v2/all')
  if (response.status === 200) {
    const data = await response.json()
    const country = data.find((country) => country.alpha2Code === countryCode)
    return country.currencies[0].code
  } else {
    throw new Error('Unable to get the currency code')
  }
}

currencyEl_two.options.selected = true를 이용해서 우리나라에서 이 사이트에 접속했다면 우리나라 통화 코드인 KRW가 기본 옵션으로 선택되어 있도록 했습니다.

//기본으로 KRW가 선택되도록
getCountryCode().then((data) => {
  return getCurrencyCode(data)
}).then((data) => {
  for (i = 0; i < currencyEl_two.options.length; i ++) {
    if (currencyEl_two.options[i].value === data) {
      currencyEl_two.options[i].selected = true
      calculate()
    }
  }
}).catch((err) => {
  console.log(err)
})

2-2. Total amount calculated as base currency amount changes

기준이 되는 통화와 환산하고 싶은 통화를 선택한 후 기준 통화의 값을 수정하면 환산한 값이 계산됩니다. 기준 통화의 최소 값을 0으로 설정했습니다.

//기준 국가코드와 환산 대상 국가코드를 활용해서 환산 대상 국가의 환율 출력하는 함수
const getResultRatesByBaseCode = async (baseCode, resultCode) => {
  const response = await fetch(`https://api.exchangerate-api.com/v4/latest/${baseCode}`)
  if (response.status === 200) {
    const data = await response.json()
    return data.rates[resultCode]
  } else {
    throw new Error('Unable to get the rate')
  }
}

//Calculating currencies
const calculate = async () => {
  const currency_one = currencyEl_one.value
  const currency_two = currencyEl_two.value
  const data = await getResultRatesByBaseCode(currency_one, currency_two)
  
  amountEl_two.value = await (data * amountEl_one.value).toFixed(4)
  rateEl.innerText = `${amountEl_one.value} ${currency_one} = ${(amountEl_two.value * amountEl_one.value).toFixed(4)} ${currency_two}`
}

2-3. Currency swapped when we click the button

환율 정보 사이의 swap 버튼은 두 국가의 환율을 바꾸어줍니다. 아랫쪽에 있던 통화가 위로 올라가면 그 통화가 기준 통화가 됩니다.

//adding event listeners
swap.addEventListener('click', () => {
  const temp = currencyEl_one.value
  currencyEl_one.value = currencyEl_two.value
  currencyEl_two.value = temp
  calculate()
})

currencyEl_one.addEventListener('change', calculate)
amountEl_one.addEventListener('input', calculate)
currencyEl_two.addEventListener('change', calculate)
amountEl_two.addEventListener('input', calculate)

3. What is improved

3-1. Used multiple open APIs

접속한 국가를 알아내기 위해 ipinfo.io의 API를 사용했고, 전세계 국가의 다양한 코드를 모아 놓은 restcountries.eu의 API를 사용해 환율 단위 코드를 가져온 후, 국가별 실시간 환율을 알려주는 open.exchangerate-api.com의 API를 활용해 기능을 구성했습니다.

3-2. Splitted requesting functions

API에서 정보를 가져오는 코드나 여러 번 호출되는 함수는 따로 다른 폴더에 분리해서 앱을 실행하는 데 필요한 최소한의 코드만 남겼습니다.

currencyEl_one.addEventListener('change', calculate)
amountEl_one.addEventListener('input', calculate)
currencyEl_two.addEventListener('change', calculate)
amountEl_two.addEventListener('input', calculate)

3-3. Scalable codes

나중에 앱의 규모가 커지고 비슷한 기능을 쉽게 추가할 경우를 생각해서 코드를 재사용하기 쉽고 눈에 잘 들어오도록 구성해보았습니다.

//BEFORE
function calculate() {
  const currency_one = currencyEl_one.value
  const currency_two = currencyEl_two.value

  fetch(`https://api.exchangerate-api.com/v4/latest/${currency_one}`)
  .then(res => res.json())
  .then(data => {
    const rate = data.rates[currency_two];
    rateEl.innerText = `1 ${currency_one} = ${rate} ${currency_two}`
    amountEl_two.value = (amountEl_one.value * rate).toFixed(2)
  })
}

//in progress
const calculate = async () => {
  //문제점: 현재 선택된 애가 아니라 AED가 나옴. fetchAPI가 너무 늦나봄... -> 마찬가지로 await으로 데이터가 들어오면 환율을 띄우는 방법으로 해결
  const data = await getCurrencyInfo()
  const rate1 = await data.rates[currency_one]
  const rate2 = await data.rates[currency_two]

  //모든 환율이 usd기준으로 되어 있어서 usd 통화와 스왑되면 제대로 환산 결과가 안 나오는 현상. usd의 경우와 아닌 경우를 나누어 고려함
  //환산한 가치가 상대 국가 통화 대비 너무 낮을 경우 값이 0으로 나와 toFixed값을 4로 늘림
  if (currencyEl_one.value !== 'USD') {
    //타겟 환율을 기준 환율로 나누어 줌
    // amountEl_one.value = 1 -> 이 설정으로 input이 안바뀌게 됨
    amountEl_two.value = ((rate2 / rate1) * amountEl_one.value).toFixed(4)
  } else {
    // amountEl_one.value = 1
    amountEl_two.value = (rate2 * amountEl_one.value).toFixed(4)
  }
}

//AFTER
const calculate = async () => {
  const currency_one = currencyEl_one.value
  const currency_two = currencyEl_two.value
  const element_one = amountEl_one.value
  const element_two = amountEl_two.value

  const data = await getResultRatesByBaseCode(currency_one, currency_two)
  element_two = await (data * element_one).toFixed(4)
  rateEl.innerText = `${element_one} ${currency_one} = ${(element_two * element_one).toFixed(4)} ${currency_two}`
}

3-4. Proper number of decimals

toFixed() 메서드를 이용하여 소수점 자릿수를 설정했습니다. 첫째 자리나 둘째 자리까지만 표현하는 경우, 통화 가치가 낮은 국가의 경우 0으로 나타나는 경우가 생겨, 적당히 넷째 자리까지 표현했습니다.

  rateEl.innerText = `${amountEl_one.value} ${currency_one} = ${(amountEl_two.value * amountEl_one.value).toFixed(4)} ${currency_two}`

4. Things to improve

API에서 정보를 불러오는 게 시간이 많이 걸리다 보니 사용자가 불편함을 느낄 수가 있습니다. 현재 작업하는 장소의 와이파이가 잘 안 터지다 보니 접속 후 우리나라 환율 코드를 불러오는 데 시간이 1초가 걸립니다(체감상 5초....). 효율적인 코드를 짜는 방법을 더 공부해야 겠다고 생각했습니다.

profile
빵굽는 프론트엔드 개발자

3개의 댓글

comment-user-thumbnail
2020년 11월 16일

혹시 어떤 인터넷강의를 수강하셨는지 알수있을까요?.? 프로젝트들 너무멋집니다 !!

1개의 답글