Installing dependencies

Once the repository is cloned locally, go ahead and access the /weather_app_tutorial directory from the terminal and run npm install to install the backend dependencies from the package.json file.

directory from the terminal and run to install the backend dependencies from the file. While still inside /weather_app_tutorial navigate into the /client directory and then do the same thing by running npm install to install all of the dependencies that are required for React.

Once the dependencies are installed, the boilerplate is ready!

The backend Express server

To get things started, we are going to set up the Express server that will be responsible for all of the backend routes, partly responsible for routing the pages, and will also be responsible for making calls to the 3rd party weather API.

Without the backend server, the React client would still run and do it’s thing regardless, it would just have zero connectivity to the backend (duh!). This is because React is running on it’s own server (port 3000), and actually connects to the backend (port 5000) by way of a proxy. This is important to know, because this is what is going to tie our frontend to it’s backend. If you check the package.json in the /client directory, you will see where this proxy has been added.

After installing all of the dependencies above, Express will now be available to use. In the root directory locate /server/server.js and open it up.

server.js

This is a quick and easy Express server that runs on port 5000.

Let’s start it to make sure everything is working. From the terminal navigate into /server and run node server.js to start up the Express server. If you head over to http://localhost:5000/ in your web browser, you should see ‘PORT 5000’. This confirms the server is up and running.

Setting up the API routes

Yeah, we could technically set up all of our routes in server.js like a bunch of cavemen, but fortunately we aren’t cavemen. A more organized approach is to set up a /routes directory that server.js can import routes from!

To overview: The /routes directory will contain any routes we need to create for this application, and then we will set up server.js to import those routes so that our front end client (React) can use them.

First we will set up the API route that is responsible for fetching weather data from the 3rd party weather API:

Open up the SearchLocations.js file that is located in the /routes/api directory. This file will eventually handle calling the weather API and capturing the users zip code from the home page (more on that later).

Take a look at SearchLocations.js :

SearchLocations.js

At first glance, we are creating a module that can be exported, hence module.exports on line 3. This module will eventually be imported elsewhere making the routes available for use.

Let’s breakdown what is going on with these POST and GET routes:

The POST route

POST route

In SearchLocations.js we have a POST route that a front end input form can use to send the users zip code to the backend when submitted. We are setting let zipcode to the value of the front end input form once it’s submitted. Note that we keep the let zipcode variable outside the scope of the POST route for a reason. It will be needed when we make our request to the weather API, so we need it to be global in this case.

We can quickly validate the zip code, and if needed, route the user to an error page. The if statement seen in the POST route handles this for us. In the US a zipcode is only 5 numbers in length. If a user enters a US zip code shorter than 5 numbers, greater than 5 numbers, or nothing at all, our POST route will redirect to the error page. Per the docs, when looking up data by zip code, the Open Weather API defaults to the US country code. This is the country code the zip code is validated for here.

We then use res.redirect('/current-weather') to redirect the page to the /current-weather URL once a user submits a valid zip code. Once the user submits a valid zip code in the front end, the input form will call the POST route in the backend, and this POST route then triggers the redirect of the page. When the page is redirected to /current-weather , this URL (with the help of React Router) will render a React component that will utilize the backend GET route.

The GET route

GET route

This GET route is called when the React component CurrentWeather.js mounts to the DOM. Remember how I said that our POST request would redirect to a URL that renders a React component via React Router ? CurrentWeather.js will be that component, but for now that is not important. When we get to working through the React side of this project, I will go into more detail regarding how and when this GET route is used.

Before moving on: Check out the API Docs for the API endpoint we will be calling below. It goes over in detail how to get specific location data, and it also goes over what data is returned.

In the GET route you’ll notice const baseUrl & const apiId right away. I have split up the API endpoint URL so that it is possible to insert the users zip code into the URL string. Since the let zipcode variable is available globally and was previously assigned a value by the POST route, we can use it in our GET route to build the weather API URL specific to the users location.

There are probably more elegant ways to split a URL and insert a string, but for a quick tutorial, this works just fine. For now const userLocation(url1, url2, zipcode) is a function that returns a string consisting of both halves of the API URL plus the users zipcode. So if you can imagine, it returns an entire URL with the user’s zipcode inserted.

We take this newly created URL now available in const apiUrl and with using this new URL in a fetch request, our backend server goes out into deep space and brings us back some weather data. If you have ever used fetch before, this is pretty standard stuff. We fetch the data, convert the response into json , and then finally we send it somewhere. When we eventually get to making a fetch request from our React front end, res.send({ data }) will be the line of code that sends the weather data from the backend to the front end fetch request.

Export the routes!

We now need to make our API routes available to the backend server. At this point our /routes directory is just hanging out by its lonesome, independent from our server.js file. As you can guess, we need to change that. Here’s how it’s accomplished.

If you take a quick look, you’ll notice in our /routes directory that we have an index.js file in addition to another directory named /api . This is an organizational tactic that separates the API routes into the /api directory, while the single index.js file handles gathering all of the routes and exporting them.

Basically we keep all of the routes like SearchLocations.js inside of the /api directory, and use the index.js file to handle exporting them. We could have 20 additional routes added to /api but regardless of how many, our single index.js file will loop through all of the available routes and export them. Let’s look at how that is set that up.

Open up server/routes/index.js :

The fs.readdirSync block of code finds and loops through all of the files in the /routes/api folder, and for each file it finds, it requires it. This is important as it allows us to export all of the routes found in the /routes/api directory. You can see how simple and organized it is to use the single index.js file to bring all of the routes together and export them at one point. Sure we only have one route for now, but this makes all the difference when things start getting more complex.

Import the routes!

This is going to happen in server.js so open it up:

server.js

require('./routes)(app) is going to import the /routes folder that contains our index.js file. Remember, the index.js file is what’s responsible for exporting all of the routes in /routes/api . By importing the /routes directory that the index.js file is located in, our backend sever will have access to every API route we create. Sweet!

Kick back and relax, that’s the backend. We can now move onto the final half of this tutorial, and that’s setting up the front end!

The front end

For this weather application I wanted to use React. If you have cloned the Github repo, you’ve probably noticed a /client directory. This directory is our React application.

Back when we first set up the project, you should have navigated to the /client directory from the terminal and ran npm install to install all of the dependencies for React. There should be a node_modules folder located inside of /client if so.

From here on our unless otherwise noted, we will be in the /client directory.

index.js

Lets get started with /src/index.js . This file is responsible for rendering our React components to the ‘root div’ (otherwise known as the entry point) in public/index.html . Aside from that, this is where we will also be using React Router to route our React components.

To start things off, go ahead and check out /src/index.js :

index.js

To briefly explain, on line 8–11 we are importing React components so that we can render them.

Line 15–21 is where we use React Router to ‘assign’ a react component to a URL path. Lets take a deeper look at line 17, 18 & 19. The '/' path on line 17 indicates that we are home. If you notice when we route to the '/' path we also render the Home.js component. Anytime the browser URL is www.ourapplication.com/ our home page component renders.

Line 18 and 19 is no different. When we visit the /current-weather path in the browser, the CurrentWeather.js component is rendered. And if we visit the /error path, ErrorDisplay.js is rendered. Easy!

Let’s start the React server!

From the terminal, navigate into the /client directory and then run npm start . This will start up the React server on port 3000. (Check out: http://localhost:3000/ if the React scripts did not launch the application automatically.)

After firing up the React server, you should see the following:

This is the home page! Albeit it simple, it does the job. You can see the input field that will capture the user’s zip code.

The Home Page

Let’s go ahead take a peak at the code for this Home.js component:

Home.js

What I want to detail is line 18–21. This is our input form that we will use to capture the user’s zip code. The form method is set to POST, and the action is set to /search-location . Remember above when we createdthe route SearchLocations.js ? Well the app.post('/search-location') route inside of that file is what our input form is posting it’s value to. When we post the input form value to app.post('/search-location') it then takes this value (which will be the zip code), validates it and then assigns it to a global variable that we can use elsewhere.

In short: