Let's create a simple Weather App with React
Published: 2021-07-31 21:10:09


## App description
Let's create a basic weather app with React(typescript), [Weather API](https://openweathermap.org/api), sass, and react hooks

[Github repo](https://github.com/Rick1196/weather-app)
[Live demo](https://weather-app-navy-chi.vercel.app/)


## Let's set our workspace
### Create our react project with create-react-app
```
npx create-react-app basic-weather-app --template typescript
```
### Now let's config linter, jest, etc.
```
npx cra-to-nx
```
This will config our dev tools
## npm packages
```
yarn add axios @fortawesome/fontawesome-free react-i18next i18next i18next-browser-languagedetector
```
- Axios for our HTTP requests
- fontawesome to display awesome icons
- i18next to add internationalization to our app
 - i18next-browser-languagedetector to detect the users default lang and set it as our defalt language

## Folder structure
NX create a larger folder structure, but This is the final structure of our project
```
 ─src
    ├───assets
    │   ├───design -> Design system
    │   │   ├───components
    │   │   ├───fonts
    │   │   ├───globals
    │   │   └───util
    │   ├───i18n -> Translations
    │   │   ├───en
    │   │   └───es
    │   └───images
    ├───components
    │   └───landing
    ├───custom-hooks
    ├───functions
    ├───interfaces
    └───services
```
## Add weather Api

### Let's create an account at [Weather API](https://home.openweathermap.org/users/sign_up)
After creating our account, let's create an API key for [Current Weather Data](https://openweathermap.org/current)
*Note: you will need to wait like 2 hours for your api key to be activated*

### Let's add our i18next config
(assets/i18n)
{% gist https://gist.github.com/Rick1196/a5942b946c96336245e22099817b780b
%}

I just add a basic translations files for EN and ES, you can find them at [src/assets/i18n](https://github.com/Rick1196/weather-app/tree/main/apps/know-weather/src/assets/i18n)

### Let's add our weather services to our project
1. If you have not created your `services` folder, create it and  inside it, let's create a new `ts` file named `weather-service`
2. Lest create our interfaces
The interfaces will serve us as data models for the Weather API responses and some other purposes

 * CurrentWeatherI (interfaces/current-weatherI.ts)
The data model of the response of the weather API's
 * WeatherPropertiesI (interfaces/weather-properties.ts)
The data model of requests to  weather API's
(interfaces/)
{% gist https://gist.github.com/Rick1196/0757426b57f267088eae90e4eeee6c64 %}

3. now let's create 3 functions
 * currentWeather

	This function will retrieve weather data by coordinates
 * getWeatherCity

	This function will retrieve weather data by city name
 * getWeatherIcon

	The currentWeahter and getWeatherCity will return an icon code in their properties, this code will serve us to retrieve an icon image to display in our app
(services/weather-services.ts)
{% gist https://gist.github.com/Rick1196/38777eaaf8897ec0a08ce9fb11dbf6f3
%}

4. Now that we have our services for the app, let's create a function to get the correct background image depending on the current weather

To achieve this, first, we need to check their current weather API documentation for their weather code at [weather codes](https://openweathermap.org/weather-conditions), i decided to group the codes by range, but you can go deeper.

(functions/weather-background.ts)
{% gist https://gist.github.com/Rick1196/ea58012889e65976b37f30020ed9fb8e
%}

You can use the same images as me, you can find them at my source code at [github](https://github.com/Rick1196/weather-app.git)

Or search for your own, i found my images at [unsplash](https://unsplash.com/)

### Our next step is to build a custom hook to get the client lat and long

For this we are gonna use window.navigator.geolocation
(custom-hook/use-position.ts)
{% gist https://gist.github.com/Rick1196/346daa98ab5865521123379e29ad3c9c
%}

This hook will provide us with the current location of our user, so now we can request the weather of the current location.

### Now let's create our main component
(components/landing.tsx)

In this component, we are gonna use the next element
- 2 buttons, one to search the location input and another to return to the current location weather
- 1 input field to search places
- A cards deck to display the weather info

#### Use our custom hook use-position
The first step to build  our component is to connect our use position custom hook to get the user position and ask for the current weather
Now that we have the position stored, let's pass it as a dependency to an useEffect hook, so every time that the position variable changes, the effect will execute the getWeather function; The getWeather function will call the getWeather callBack, await for the service response then results will be store at the weather state; then the functions getWeatherIcon and readWeatherImage will be call and this functions will update the watherIcon and weatherImage state respectively, the change at weatherImage will trigger the effect to set the image as the body tag background image property value.

Now that we have the weather, the weatherImage and the weatherIcon, we can use this data to show it to the user.

(components/landing/landing.tsx)
{% gist https://gist.github.com/Rick1196/edb0e2fe57188fd9fc98350f1dc0cf25
%}

## Where to know more about the topics to build a basic project like this?
- (react hooks)[https://reactjs.org/docs/hooks-intro.html]
- (react custom hooks)[https://reactjs.org/docs/hooks-custom.html]
- (geolocation api)[https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API]
- (react-18n-next)[https://react.i18next.com/]
- (react-form-hooks)[https://react-hook-form.com/get-started]
- (Nx)[https://nx.dev/latest/react/getting-started/intro]

## Wher is the sass explanation??
I will write a second post to cover the design of the project

[Let's create a simple weather app - Part 2]()