- Part 1: Backend (Server-side)
- Part 2: Frontend (Client-side)
- Part 3: Connecting both piece together
- Part 4: Deployment
Source Code — https://github.com/JinKim7/mern-weather-app
Demo
We’ll be building a weather web app called Weathering With You.
This app will be able to let you, the user, enter a zip code, choose Celsius or Fahrenheit, and then get the current weather data at that time when you click Save.
This app uses a free weather API that we will utilize and store that data in local storage/mongo, per your choosing, and use Redux as a state manager so everything updates super quickly when interacting w/ the UI.
The left-hand panel will be the current zip code’s weather information and the right-hand panel will be a list of 10 most recent queries.
Also, if you queried 1 zip code and refresh the page, it will update the left-hand panel to the current weather information for the most recent zip code you have queried.
Demo: https://mernweatherapp.herokuapp.com/
**disabled mongo connection in this app — but this tutorial can show you how to connect and use
What can it do? What will I learn from the entire project? What technologies will I use?
- Learn to use a free API, openweathermap’s weather API, to dynamically get weather data based on zip code (USA only)
- Aside from MERN (Mongo Express React Node), we’ll be including Redux as our state manager
- Ability to save data into LocalStorage so that data is stored locally and don’t need to rely on Mongo (depends on use case)
- React Bootstrap as our frontend component library
Getting started
Install Node (at the time of this writing, current stable version of this tutorial is v12.18.3) by going to the website and clicking Download
To verify if it has downloaded correctly — go to your terminal and check which version of Node you download by typing this in command line:
node -v
Once Node version is confirmed, create a new directory called
mern-weather-app and then go into that folder.
These are the commands to create a new directory and change directories within command line:
mkdir mern-weather-app
cd mern-weather-app
We can now initialize our project using npm within the root folder of our mern-weather-app
by using this command:
npm init -y
Now, we can install all the dependencies that we need:
npm i axios body-parser cors dotenv express mongoose
Here is the list of all the dependencies we just installed:
- axios: HTTP client
- body-parser: body parsing middleware
- cors: Cross-Origin Resource Sharing middleware
- dotenv: loads environment variables from a
.env
file intoprocess.env
- express: web application framework for Node
- mongoose: MongoDB object modeling tool
*I included the links to all the dependencies home page, so feel free to check out more info about them.
Now let’s install our dev-dependencies, which are packages that’ll help us be more efficient during our development process, but won’t be included in our Production build:
npm i -D nodemon concurrently
- nodemon: automatically restarts node app when file changes are detected
- concurrently: runs multiple commands concurrently
Add .gitignore
Add a .gitignore
file to your root directory so that when you push your project to github, we do not push any sensitive data or unnecessary files.
Download Git
Download Git for your specific operating system and run it.
Once downloaded, in your terminal/command line, check to see if it’s working by checking the git version that you have
git --version
We need git to connect to github and make commands to utilize version control.
Connect to Github
- Go to https://github.com/new to create a new repo or click on any action button in github to create a new repo(make an github account if you don’t have one already)
- Create a repo name for what you want to call this project, choose either public/private, I’d suggest Private in case you push anything sensitive (like api key or mongo connection credentials) by accident to your repo
3. After you created a repo, you should see this screen:
4. We’re going to follow the …or create a new repository on the command line instructions, but not all of it line-by-line.
5. Go back to your project’s terminal and make sure you’re in the root directory. These are the commands that we’ll use to connect to our newly created repo.
git init
git add .
git commit -m "first commit"
git remote add origin https://github.com/[username]/[app name].git
git push -u origin master
6. You should now see your project when reloading your project page on github
Checkpoint #1 — https://github.com/JinKim7/mern-weather-app/tree/1.setup-packagejson%26gitignore
File Changes — https://github.com/JinKim7/mern-weather-app/pull/1/files
Your working project directories should look similar to the checkpoint above. These checkpoints will lead you to branches that are code complete with everything we have done thus far.
So, you can refer to them if you need guidance on where some of the code should be placed and whatnot.
Create Backend Server
Make a new directory called server
within the root directory and then create a server.js
file to be like this.
require("./api")
in line 14 — This means that we’re going to use an entire directory to organize all our API endpoints instead of putting all the API endpoints inserver.js
Now, create a new directory called api
in the /server
directory and create two files, index.js
and weather.js
- There are comments within each file to briefly explain what most of the lines of code does, but here’s a brief explanation…
weather.js
— we’re creating a weather class to be able to connect to the weather api and be able to get weather data to send back to our frontend later on in this tutorial.index.js
— depending on which type of endpoint we call, this will be where our router lives to help direct which type of traffic goes where. i.e, if we have a GET/weather
endpoint call, our router is able to dictate what kind of operations need to take place to satisfy the call as expected. Same goes for the POST request.
Checkpoint #2 — https://github.com/JinKim7/mern-weather-app/tree/2.setup-server-and-apis
File Changes — https://github.com/JinKim7/mern-weather-app/pull/3/files
Create Environment Variable file | Use Weather API Key
One thing mentioned in the weather.js
file that we have not done yet is creating a file for environment variables (more info on what env vars are here).
Before we create an .env
file, let’s get our weather api key since we’ll be using it within this file.
Got to https://home.openweathermap.org/api_keys and create a profile (the direct link should already take you to the API keys
page, if you’re already logged in).
Now, create an .env
file within the root directory (mern-weather-app
) and include this in that file:
WEATHER_KEY=[weather API key from home.openweathermap.org/api_keys]
or more of an obvious example: WEATHER_KEY=b8a1e654asdf654asdf654
Note: assuming
b8a1e654asdf654asdf654
was my real API key (fyi, not my real API key for the 1337 h4x0rs).
All-in-all, it should look like this (also double-check the file/folder structure):
Checkpoint #3 — https://github.com/JinKim7/mern-weather-app/tree/3.ENV-file
File Changes — https://github.com/JinKim7/mern-weather-app/pull/4/files
❗️❗❗ Do not push your .env
file to Github because if your repo is public, everyone can see your secret credentials❗️❗❗
- I’m including an
ENV
file that’ll have comments within the file on how to make the.env
file.
Test What We Have So Far
To test our weather API thus far, add this script to the package.json
"start": "node server/server.js"
Now, you can run the command, npm run start
, within your terminal to test our static GET endpoint to the weather API to get the weather data for zip code 98052
within the US (United States) by going to the URL localhost:5000/api/weather
Connect to Mongo
Create a new account at mongodb.com and you will land on this page to Create a cluster
Choose the FREE tier when creating a cluster.
On the configuration page for creating your cluster, these are the options you will want to choose:
- aws
- Oregon (bc I live on the west coast, if you live in east coast, choose N.Virginia — if you live in the mid area…pick your poison)
- M0 Sandbox
- No Backup
- Customize your cluster name if you want to…I’m not.
This should be the main page you end up on when your cluster has been created:
- Database Access — this will allow certain users, restricted permissions on what they can do once connected to the database.
You will need to create a new user, so you can use this newly generated user’s credentials to connect to mongo from your app.
*fyi, only using this user/pass combo as temp credentials to show the example more clearly. It will already be deleted by the time this tutorial is published.
2. Network Access — this will give you access to connect to your mongo database based on which network is connecting to it. It could be your personal IP or anywhere from the world.
*I chose Allow Access From Anywhere
for the sake of this tutorial and only temp. You will be unsuccessful if you try to hack attack me.
3. Connect — will give you the connection string for us to use within our code to route and connect to mongodb.
- Choose Connect your application to get our connection string
- We can now see the connection string to copy/pasta within our code:
mongodb+srv://jin:<password>@cluster0.luzag.mongodb.net/<dbname>?retryWrites=true&w=majority
More obvious example:
mongodb+srv://jin:t4EoZWQdJiyOPsu9@cluster0.luzag.mongodb.net/Cluster0?retryWrites=true&w=majority
Add the mongo connection string to your .env
file and have your key be DB
for your connection string to follow suit.
Your .env
should look like this now:
To connect to mongo, we first need to add/update some files.
First, updating the server file. We are using the mongoose
package to connect to mongo below…
- using
process.env.DB
to get the DB key andmongoose
to connect to the database
Run npm run start
and you should see Mongo Connected...
with your terminal.
If mongo does not connect, then…
- double-check you have the right ip address whitelisted (possible your ISP changes your IP address after a few days making it dynamic, or using connect from anywhere option)
- Your username/password match and the password actually created the user (if you used an easy password like
password123
, it will not create it for you and have to use a diff password) - The dbname is the same casing as you see within the UI
- the routing to the
.env
file is correct - many other possibilities why it’s going wrong 🙃
Update Files to Integrate Mongo
We are adding a database model for our weather data which is going to be used to template out the structure of what’s going to be saved within mongo.
Create a new folder and file called src/models/Weather.js
below:
- This model is based off the structure the weather api will give us here.
Update the server/api/weather.js
file to take in weather data and save it into the mongo database; if a document already exists, then we want to replace it (upsert) based on the zip code as our unique identifier, if the document doesn’t exist, then add the weather data.
const Weather
— let’s us use the weather model that we just createdsaveWeatherDataToMongo
— execute mongo operations to save the weather data uniquely based on the zipcode filter (replace if a zipcode already exists in mongo, if not, create a new document and save).
- This is the specific endpoint we’re using: https://openweathermap.org/current#zipgetWeatherDatafromMongo
— tries to find a document w/ the same zipcode, if it cannot find one, then it will returnnull
findOneReplace
— helper method to find and replace in mongo
Finally, add the post request in server/api/index.js
so we can store weather data into mongodb.
- the POST
/weatherMongo
will be used later on in the tutorial when connecting frontend to backed. - the GET
/weatherMongo
won’t be used in our tutorial, but it’s here for you to play around with it.
Checkpoint #4 — https://github.com/JinKim7/mern-weather-app/tree/4.mongo-integration
File Changes — https://github.com/JinKim7/mern-weather-app/pull/5/files
Let’s test our Mongo integration!
- run
npm run start
in the terminal of your root directory to start your backend server - Go to http://localhost:5000/api/weatherMongo?zipCode=98052 to test out your
GET
request to see if your endpoint is working and be able to get weather data.
Surprise! You should seenull
on your screen
- We’re seeing
null
because our mongodb does not have the weather data information yet. Since we don’t have our frontend to make our POST calls to the backend, we’ll have to use our Console to make the POST call for us (or you can you Postman or any other REST api clients — you can find some good chrome extensions). - Copy/pasta this code snippet into your chrome console (right-click > inspect > Console tab)
fetch('http://localhost:5000/api/weatherMongo', {
method: 'POST',
body: JSON.stringify({
zipCode: 98052,
tempMetric: "imperial"
}),
headers: {
'Content-type': 'application/json; charset=UTF-8'
}
})
.then(res => res.json())
.then(console.log)
- Refresh the page and now it should populate the weather data from mongodb.
- Now, to check the data saved in mongo, go to cloud.mongodb.com (it should redirect you to your dashboard if you’re already logged in, if not, log back in) and click on the
Collections
tab
Done!…for now…(you finished the longest section of this series).
In the next section, we’ll move onto frontend for this application!!!
Additional Resources
Here are links to further your knowledge on all the tech we used today.
- Terminal Commands — https://dev.to/kymiddleton/reference-guide-common-commands-for-terminal-6no
- Node
- NPM Packages — search for the packages you’re curious about on this site
- Github — create your own projects and contribute to open source projects
- what is a .gitignore file
- what is git
- what is a client, a server, or whatever?
- what is frontend and backend?
- what is a .env file
- what is an api
- Mongo
- Mongo-mongoose model
- OpenWeather — api key and https://openweathermap.org/current#zip endpoint
- Chrome DevTools (includes html overview, console, networking, etc)
Similar Tutorials
Here are other tutorials that also give similar teachings, but we all have our own unique ways of teaching and presenting data.
Hopefully, one of these, or mine, helps you to become successful in learning of what you came here for 😃
They’re all PHENOMENAL(!!!) tutorials and highly recommend them! My tutorial glosses over technology-specific details