A NodeJS solution to view weather data on any location via browser or through the REST API
The goal of this project was to come up with some way to proxy weather data from a real source, extract only the data I think would be needed, and send that back. On top of that I wanted some way to include a front-end portion. I debated between what to use. I have experience in NodeJS w/ the Express framework. Some NodeJS projects like a discord bot and a twitch bot. However more recently I've been learning Flask and working on a project to scrape and chart reddit analytics. Flask is good for getting started quickly, and NodeJS has a lot of support and is something I'd like to get even more familiar with. I also feel more comfortable in Node, so I decided to go with that as my backend.
With that in mind I wanted to chart out a little more of how the front-end would look. I wanted the user to be able to:
- register an account
- login/logout
- add or remove weather entries of different cities and have that info stored on their account for anytime they login
Project diagram and intial front-end plan (bottom-left)
Main page for viewing weather data and adding new cities
Login/Register account page
On top of this I wanted to deploy this all on a platform to host. I decided to use a well-known PAAS called Heroku to host. Which will allow me to do this for free as well and host my NodeJS instance. Since I'll want to store user data which is perfect since they also provide a DB to use.
Modules used and reasoning:
- Express - I could have used the basic http module and used http.createServer(...) to handle incoming requests. However Express provides an elegant and easy way - to create endpoints, plus I'm already familiar with it.
- node-fetch - Very similiar to window.fetch in Javascript in the browser, this allows me to get a Promise of a request. Needed for proxying between the user and open weather map.
- cors - Allows us to communicate between react and our api endpoints on Express
I created an account for getting weather data and found current and hourly API endpoints to use. I also created a Heroku account to deploy later on.
- I realized there was no simple way for Heroku to get my API key and use it from a file (my original solution). So I had to get rid of the file solution and implement an environment variables solution with an env.bat file
- I decided to use React as the UI library, however my project was created already. Had some permissions issues involving network drives and installing the react-scripts. Found a helpful tutorial. Unfortunately some issues still persisted so I create a new react app entirely and manually merged into this repo.
- I couldn't wrap my head fully around how to link Express and React together. With a little bit of hair pulling I figured out running both concurrently requires having the React app in its own folder within the repo. Then setting package.json to run a postbuild script on Heroku to build React and run it as well. See how to deploy
- I get data to the front-end by having React and Express running on separate ports. Then having React make GET requests to Express's API and having that update the state of the components. Since They are running on separate ports CORS is needed.
- I do two separate fetch calls to my api for each weather widget (one for current and one for hourly weather data), this could be optimized in the future to be able to do a batch call of all of the widgets data. Due to time limitations, this is how it is for now.
- React generates a lot of files on its own, I plan on trimming and doing cleanup as I finalize the project.
- I realized openweatherdata's API JSON for hourly data forecast includes UTC as a Date string, as a future edition, I'd calculate the timezone and do conversion. We'll work with UTC to keep it more consistent
Some further widget and component planning below
- React is very similiar to UI5 except with some syntax changes. There are components that have their own state that control what is shown on the DOM.
The date you're submitting this. February 16th, 2021
If applicable, please provide the url where we can find and interact with your running application.
Deployed to Heroku
To access APIS (examples):
Current weather data:
Upcoming morning data (3 hour increments):
Validate city:
You can hit API endpoints locally by going to http://localhost:5000
How much time did you spend on the assignment? Normally, this is expressed in hours.
- Planning - 2 hours
- Setup - 1 hour
- Implementing api endpoints with documentation - 2.5 hours
- Filling out Readme - 1 hour
- Linting - 30 minutes
- Heroku deployment and environment variable setup - 1 hour
- React setup and Heroku adjustments - 3 hours (some issues)
- Weather widget w/ communication to backend api - 2 hours
- Weather widget and design completion - 2 hours
- Parent and child components, event handling, adding cities - 3 hours
Use this section to tell us about any assumptions that you made when creating your solution.
- Deploying with React+Express to Heroku would be simple. It proved to be the main time killer.
- React being somewhat similiar to UI5 at SAP. Making it easier to learn.
If applicable. Did you do something that you feel could have been done better in a real-world application? Please let us know.
- I'm going to leave out the DB and login with JWT token due to time limitations. I believe squeezing it in will make the overall project lower quality, I prefer to ship on time and have it done right
- Using UTC time instead of city specific local time for hourly forecast. This is done for consistency and simplification.
If applicable, use this area to tell us what stretch goals you attempted. What went well? What do you wish you could have done better? If you didn't attempt any of the stretch goals, feel free to let us know why.
- Build a simple UI for the service
- Deploy your API
- Proxy a real weather API via your service to fetch the actual weather.
- I used open weather map to fetch current and hourly weather data for different cities. This worked surpringsly easily along with the node-fetch module. The membership is free and allows for what I needed in this project.
If applicable, please provide us with the necessary instructions to run your solution.
npm install
(installs Express dependencies)npm run client-install
(installs React dependencies)- Open env.bat and put in API key for openweatherorg
\env.bat
(run via cmd window)npm run dev
(run via cmd window)
- If runninng locally, to hit API endpoints (Express):
- To hit main page (React):
If running on heroku, run heroku config:set API_KEY=YOUR_API_KEY_HERE
Were you short on time and not able to include something that you want us to know about? Please list it here so that we know that you considered it.
A reference to helpful videos that assisted me
Some ideas that didn't quite make the cut (either to complexity, no access to an API, or lack of expandibility):
- Get weather of planets in the solar system. Have a space themed UI
- no real world API to query live planet weather data. This would miss one of the stretch goals
- Get the time and weather of Minecraft servers
- biome and position dependent, would need a live server not to crash. Would make sense if had access to multiple servers. Can't see a real use case here for me
Have feedback for how we could make this assignment better? Please let us know.
Building a Full Stack solution for this problem was a lot of fun, quite the challenge! Its been very fun learning how to build an application like this from the ground up. Took me longer than expected.