Skip to content

A full-stack, step-by-step development project: An Embedded Javascript (EJS) Progressive Web App using NodeJS-Express scaffolding to call weather API providers for weather reports.

Notifications You must be signed in to change notification settings

hurricanemark/Weather_Report_NodeJS_EJS_Express_WeatherBit_API

Repository files navigation

A Responsive NodeJS-Express Web App With Stepwise Implementation

This project is intended for the beginner to novice javascript developers who are interested in the nuts and bolts of implementing a working web application using various frameworks and libaries. Although this only scratches the surface of a real-life software development project, you will experience what it takes to bring an idea to fruition.


wireframe

Weather Service

Ever wonder why your phone shows weather data of your immediate vicinity on your travel? This project demonstrates the use of Navigator.geolocation API that is part of NodeJS to pinpoint your immediate location. The geolocation method gets the current position in longitude and latitude. The weather app uses these values to call a weather service API for weather data. This non-interactive process happens automatically for your convenience.

Sample output

Client display


The Value of Weather Information

Weather information is powerful knowledge used in forecasting the production of certain operations to help determine the economic bottom line. There are countless human endeavors affected by weather factors. Rain is good for growers, and forewarning is valuable in extreme weather, while the sunny sky and windy days could be good for energy production. For example, solar power production needs to know the number of hours of sunlight specific to geographical location. Wind farm needs to know wind speed, direction, etc. The travel and hospitality industry is most affected by dynamic weather patterns. From agriculture to space-faring, weather plays a key role in the decision-making process.

There are weather detection stations situated in and around you. The inner working of making data available is not of interest to the populous but it is vital to a functioning society. Although, the National Weather Service is a government agency that disseminates data free of charge. Weather data has been monetized by repackaging in ways the population can consume. e.g. Local TV news reserve a segment devoted to weather ubiquitously. Weather data is available at your fingertips. It is all factored into a transferable cost by some service providers you're currently paying. For weather application developers, the effective cost per thousand impressions (eCPM) metric is higher compared to educational apps. You can effectively monetize your project if you do it right.


Below is the template for a rudimentary completion of an example on interfacing with a weather data provider.
For indepth logics and real life data implementation, continue to HERE!.


NodeJS and Express

I recently wrote this weather reporting app using the cloud editor replit where the bootstraping of node JS is hidden. All I had to do was to focus on the core logic in app.js, style.css, and index.html. To create a fully functional development environment locally, I needed to bootstrap NodeJS, Express to my replit code.

Here is how I add scalffolding my Nodejs project.

Configure Project Development Environment for ES6

Let's assume you are using NodeJS with a version later than 13. Then, it is required to configure the development environment to work for ExpressJS with dotenv and ES6 modules.

First, you will need to change your package.json to include:

...
"type": "module",
...

Then, use imports in your index.js. Here is an express start with dotenv:

import dotenv  from "dotenv"
import express from "express"

dotenv.config()

const app = express()
const port = process.env.PORT || 5000

app.get('/', (req, res) => {
  res.send("Local Weather.  Don't leave home without reading it")
})

app.listen(port, () => {
  console.log(`Local weather server is serving you from http://0.0.0.0:${port}`)
})

Step 1: Migrate replit code to local VSCode. Create a folder for your project. Create sub folders views and public to place client-side programming.

`mkdir views`

`mkdir public`

Step 2: Initialize the folder as a node project

` npm init -y`

Step 3: Install express to configure a lightweight Node server

`npm install express`

Step 4: Install helmet to configure runtime security

`nmp install helmet`

Now, you are good to start developing and running from VSCode.

Project Layout

It is a typical NodeJS project layout.

'index.js' - server file

'./public/script.js' - interface to https://weather-proxy.freecodecamp.rocks/api/

'./views/index.html' - client-side presentation.

Runtime

npm start

Initially, the browser might pop up asking if you would allow it to detect your location. An 'Allow' will enable GPS pinpoint weather report. A 'Block' will disable GPS for current and subsequent sessions.

Browser popup


Build Once, Run Anywhere!

Generate A Docker Image

If you pulled or cloned this code base, replace my dockerhub username 'marknre' with your own DockerHub's username.
Using the correct DockerHub username ensures error free docker push operation.

Build a docker image base on the given Dockerfile and .dockerignore is this folder.
After successful docker build, run the image to verify correctness.
Then it can be pushed to dockerhub or your favorite cloud provider.

docker build -t marknre/techrolemiweatherapp:2.0 .

docker build -t marknre/techrolemiweatherapp:2.0 .      

[+] Building 3.1s (11/11) FINISHED
 => [internal] load build definition from Dockerfile                                                  0.0s 
 => => transferring dockerfile: 32B                                                                   0.0s 
 => [internal] load .dockerignore                                                                     0.0s 
 => => transferring context: 2B                                                                       0.0s 
 => [internal] load metadata for docker.io/library/node:16.17.0                                       1.1s 
 => [auth] library/node:pull token for registry-1.docker.io                                           0.0s 
 => [internal] load build context                                                                     0.4s
 => => transferring context: 635.22kB                                                                 0.3s
 => [1/5] FROM docker.io/library/node:16.17.0@sha256:a5d9200d3b8c17f0f3d7717034a9c215015b7aae70cb2a9  0.0s
 => CACHED [2/5] WORKDIR /app                                                                         0.0s
 => CACHED [3/5] COPY package.json ./                                                                 0.0s
 => CACHED [4/5] RUN npm install                                                                      0.0s
 => [5/5] COPY . .                                                                                    0.9s
 => exporting to image                                                                                0.7s
 => => exporting layers                                                                               0.6s
 => => writing image sha256:1c4db40ce8799665d8226aea4ae5759b3dc17c0538992b95e59b2e74375da1c7          0.0s
 => => naming to docker.io/marknre/techrolemiweatherapp:2.0                                           0.0s

List the image

PS D:\DEVEL\NODEJS\BrainUnscramblers\StagingProjs> docker image ls
REPOSITORY                              TAG          IMAGE ID       CREATED              SIZE
marknre/techrolemiweatherapp            2.0          08134bd887f1   About a minute ago   954MB
marknre/techrolemiweatherapp            1.0          dc6e0acce1d7   2 days ago           947MB

On the DockerHub registry

A docker image built with this git-tag:Phase1-Extened-Weather-Forecasts is available to the public on the DockerHub registry. You can pull it with the command below:

docker pull marknre/techrolemiweatherapp:latest

Run docker

Notice that environment variables (secret keys) required to run the app is not being included in the Dockerfile. These secret keys will be stated with the container.
eg. ... -e WEATHERBIT_KEY=XXXXXXX

Notice also that Dockerfile exposes port 8080. This needs to be forwarded to a port on your local machine. i.e. LOCAL_PORT:CONTAINER_PORT for example 4321:8080

docker run -p 4321:8080 --memory=128m -e WEATHERBIT_KEY=Actual_Secret_Key_for_Weatherbit bb89b0646be4


Docker container


To access the Local Weather app running in docker container, point your browser to the forwarding port 4321.

http:/localhost:4321


Hosting on A Public Site

For the purpose of hosting this app, we select Cyclic free-for-life tier. Cyclic deploys full stack NodeJS apps on AWS infrastructure directly from GitHub. It works by integrating with your GitHub repos. It will build and deploy your code on every merge or push to your default branch.

Build log on Cylic

To avoid building from the main branch on Cylic, you can specify build source as a git staging branch.

2022-11-19 08:49:39: [CYCLIC] Building...
2022-11-19 08:49:39: [CYCLIC] cloning...
2022-11-19 08:49:40: From https://github.com/hurricanemark/Weather_Report_NodeJS_EJS_Express_WeatherBit_API
 * branch            46b9aa68f54072cc8cf20f8936c79ad2bceaf306 -> FETCH_HEAD
2022-11-19 08:49:40: HEAD is now at 46b9aa6 Merge pull request #62 from hurricanemark/Phase4-TeamRolEmiSeriousWorks
2022-11-19 08:49:40: [CYCLIC] verifying...
2022-11-19 08:49:40: [CYCLIC] using: node:v16.18.1 npm:8.11.0 runtime:nodejs16.x
[CYCLIC] building from: /
2022-11-19 08:49:40: [CYCLIC] installing dependencies from: package-lock.json
2022-11-19 08:49:40: npm
2022-11-19 08:49:40:  WARN config production Use `--omit=dev` instead.
2022-11-19 08:49:47: npm 
2022-11-19 08:49:47: WARN deprecated w3c-hr-time@1.0.2: Use your platform's native performance.now() and performance.timeOrigin.
2022-11-19 08:49:48: npm 
2022-11-19 08:49:48: WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
2022-11-19 08:49:48: npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
2022-11-19 08:49:50: npm WARN
2022-11-19 08:49:50:  deprecated har-validator@5.1.5: this library is no longer supported
2022-11-19 08:49:51: npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
2022-11-19 08:49:59: 
added 925 packages in 18s
2022-11-19 08:49:59: npm notice 
npm notice New major version of npm available! 8.11.0 -> 9.1.2
npm notice Changelog: <https://github.com/npm/cli/releases/tag/v9.1.2>
npm notice Run `npm install -g npm@9.1.2` to update!
npm notice 
2022-11-19 08:49:59: [CYCLIC] running build if defined...
2022-11-19 08:49:59: [CYCLIC] pruning dev dependencies...
2022-11-19 08:50:01: 
up to date, audited 489 packages in 2s
2022-11-19 08:50:01: 
52 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
2022-11-19 08:50:01: [CYCLIC] packaging 187.66 MB...
2022-11-19 08:50:01: [CYCLIC] bundling from / ...
2022-11-19 08:50:06: [CYCLIC] done packaging
[CYCLIC] deploying...
2022-11-19 08:50:16: deployed us-west-2 -  10.168s
2022-11-19 08:50:16: SUCCESS

took 36.7 seconds
api deployed at:
https://cute-teal-pigeon-sari.cyclic.app

Please do not abuse this live website below. Thank you! Live demo

Recommend Cylic https://app.cyclic.sh/#/join/hurricanemark

Test Automation

Selenium is an opensource providing QA testing environment best fit for test automation. Selenium supports multiple languages such as Java, Python,CSharp, Ruby, Javascript, and Kotlin.

We will choose Selenium IDE chrome extension to configure and run a simple user-interface automation test project.

  1. On the Chrome browser, download selenium chrome extension.

  2. Write test cases as follow and click Run all tests:

UI-Automation


  1. Save the Selenium script as ./public/tests/SeleniumIDE_ChromeTestWeatherBitApp.side

  2. Install selenium-side-runner, then run the test script above from the command console.

  StagingProjs> selenium-side-runner .\public\tests\SeleniumIDE_ChromeTestWeatherBitApp.side -c "browserName=chrome"

  info: Running test UITests
  info: Building driver for chrome

  RUNS  C:/Users/markn/AppData/Roaming/npm/node_modules/selenium-side-runner/dist/main.test.js
  info: Driver has been built for chrome
  info: Finished test UITests Success
  PASS  C:/Users/markn/AppData/Roaming/npm/node_modules/selenium-side-runner/dist/main.test.js
    Running project TestWeatherBitApp
      Running suite Default Suite
        √ Running test UITests (2086 ms)

  Test Suites: 1 passed, 1 total
  Tests:       1 passed, 1 total
  Snapshots:   0 total
  Time:        2.75 s, estimated 7 s
  Ran all test suites within paths "C:\Users\markn\AppData\Roaming\npm\node_modules\selenium-side-runner\dist\main.test.js".

  StagingProjs>

Convert Web App into Mobile App

The advantage of designing and implementing a responsive web app earlier is now paying off. If you were to open it using the browser on your phone. Its looks-and-feel is fine.

Before you invest time and effort developing mobile-native, convert this hosting URL using online converter such as GoNative.

We also select AppsGeyzer to make another conversion for good measure. Download mobile image here.

Often, this is enough to demonstrate proof of concept. You can use it to make further decision in your mobile development.

iOS Data Screen iOS Screenshot