i have recently built this simple weather-app. I would be happy to get some criticisms to improve my code.
Structure:
app.js:
import '../sass/style.scss'; import '@fortawesome/fontawesome-free/js/all.min'; import 'regenerator-runtime/runtime'; import elements from './modules/elements'; import update from './modules/document'; (() => { function run(cityName) { update(cityName); setInterval(() => update(cityName), (60000 * 10)); } run('homs'); elements.form.addEventListener('submit', (e) => { e.preventDefault(); run(elements.search.value); }); })(); modules/apis.js
/* eslint-disable no-undef */ import axios from 'axios'; const apiWeather = { base: 'http://api.openweathermap.org/data/2.5/', key: process.env.API_TOCKEN_WEATHER, query: '&units=metric', }; const apiTime = { base: 'http://api.openweathermap.org/data/2.5/', key: process.env.API_TOCKEN_WEATHER, query: '&units=metric', }; export function getWeather(city) { return axios .get(`${apiWeather.base}weather?q=${city}&appid=${apiWeather.key}${apiWeather.query}`) .then((response) => response.data).catch(() => false); } export function getTime(uluru) { return axios .get(`${apiTime.base}onecall?lat=${uluru.lat}&lon=${uluru.lon}&exclude=hourly,minutely,daily,current&appid=${apiTime.key}`) .then((response) => response.data).catch(() => false); } export function getMap(uluru, mode, id) { const mapId = mode === 'dark' ? process.env.API_TOCKEN_MAP_DARK_ID : false; const { lat, lon: lng } = uluru; const map = new google.maps.Map(id, { zoom: 8, center: { lat, lng }, mapId, }); // eslint-disable-next-line no-unused-vars const marker = new google.maps.Marker({ position: { lat, lng }, map, }); } modules/document.js
import elements from './elements'; import icons from './icons'; import { getWeather, getTime, getMap } from './apis'; import { count, getMode, getIconWeather, getIconCountry, innerHTML, getCurrentDate, formatDate, information, } from './helpers'; function addClassNameToBody(className) { if (!elements.body.classList.contains(className)) { elements.body.classList = ''; elements.body.classList = className; } } export default async function update(cityName) { elements.error.classList.remove('active'); elements.loading.classList.add('active'); const city = await getWeather(cityName); if (!city) { elements.error.classList.add('active'); elements.loading.classList.remove('active'); return; } const info = information(city); const time = await getTime(info.uluru); const currentDate = getCurrentDate(time.timezone); const mode = getMode(currentDate, { uluru: info.uluru, sunset: info.sunset }); const weatherIcon = getIconWeather(icons, { status: info.status, mode }); const countryIcon = getIconCountry(info.country); elements.loading.classList.remove('active'); addClassNameToBody(mode); innerHTML(elements.city, (`${info.name},${info.country} ${countryIcon}`)); innerHTML(elements.date, formatDate(currentDate)); innerHTML(elements.description, info.description); innerHTML(elements.icon, weatherIcon); innerHTML(elements.pressure, Math.round(info.pressure)); innerHTML(elements.humidity, Math.round(info.humidity)); innerHTML(elements.wind, Math.round(info.wind)); innerHTML(elements.visibility, Math.round(info.visibility / 1000)); count(elements.temp_main, Math.round(info.temp)); count(elements.temp_min, Math.round(info.temp_min)); count(elements.temp_max, Math.round(info.temp_max)); count(elements.feels_like, Math.round(info.feels_like)); getMap(info.uluru, mode, elements.map); } modules/elements.js
export default { body: document.querySelector('body'), form: document.querySelector('.search form'), search: document.querySelector('.search form input'), loading: document.querySelector('.loading'), error: document.querySelector('.error'), city: document.querySelector('.city'), date: document.querySelector('.date'), temp_main: document.querySelector('.main'), temp_min: document.querySelector('.temp-min'), temp_max: document.querySelector('.temp-max'), feels_like: document.querySelector('.feels-like'), pressure: document.querySelector('.pressure'), humidity: document.querySelector('.humidity'), wind: document.querySelector('.wind'), visibility: document.querySelector('.visibility'), description: document.querySelector('.description'), icon: document.querySelector('.icon'), map: document.querySelector('.map'), }; modules/helpers.js
export function innerHTML(elm, value) { elm.innerHTML = value; } export function information(city) { return { name: city.name, country: city.sys.country, status: city.weather[0].main, description: city.weather[0].description, temp: city.main.temp, temp_min: city.main.temp_min, temp_max: city.main.temp_max, feels_like: city.main.feels_like, pressure: city.main.pressure, humidity: city.main.humidity, wind: city.wind.speed, visibility: city.visibility, uluru: { lat: city.coord.lat, lon: city.coord.lon }, sunset: city.sys.sunset, }; } export function count(elm, _new) { let finish = false; let old = Number(elm.innerText); const counting = setInterval(() => { if (old > _new) { old -= 1; } else if (old < _new) { old += 1; } else { finish = true; clearInterval(counting); } innerHTML(elm, old); if (finish) elm.classList.toggle('active'); }, 100); } export function dateToTimestamp(date) { return new Date(date).getTime() / 1000; } export function formatDate(data) { return new Date(data).toLocaleString('en-US', { day: '2-digit', month: 'long', year: 'numeric', weekday: 'long', hour12: false, hour: 'numeric', minute: 'numeric', }); } export function getCurrentDate(timeZone) { return new Date().toLocaleString('en-US', { timeZone }); } export function getMode(currentDate, city) { return city.sunset >= dateToTimestamp(currentDate) ? 'light' : 'dark'; } export function getIconWeather(icons, city) { const { status, mode } = city; const index = icons.natural[status.toLowerCase()] ? 'natural' : mode; return icons[index][status.toLowerCase()]; } export function getIconCountry(code) { return `<img src="https://openweathermap.org/images/flags/${code.toLowerCase()}.png" title="${code.toLowerCase()}"/>`; } modules/icons.js
export default { light: { clear: '<i class="fas fa-sun"></i>', clouds: '<i class="fas fa-cloud-sun"></i>', rain: '<i class="fas fa-cloud-sun-rain"></i>', }, dark: { clear: '<i class="fas fa-moon"></i>', clouds: '<i class="fas fa-cloud-moon"></i>', rain: '<i class="fas fa-cloud-moon-rain"></i>', }, natural: { snow: '<i class="fas fa-snowflake"></i>', fog: '<i class="fas fa-smog"></i>', mist: '<i class="fas fa-smog"></i>', smog: '<i class="fas fa-smog"></i>', drizzle: '<i class="fas fa-cloud-rain"></i>', storm: '<i class="fas fa-poo-storm"></i>', bolt: '<i class="fas fa-bolt"></i>', wind: '<i class="fas fa-wind"></i>', rainbow: '<i class="fas fa-rainbow"></i>', }, }; 