This project require to create an asynchronous web app that uses Web API and user data to dynamically update the UI.
The starter project has some HTML and CSS styling. To achieve the desired functionality, it required modifying the server.js
file and the website/app.js
file. And using index.html
for element references. P.S: The app is functioning correctly but looks ugly still, will add some styling at some point.
- Install Node.js from official site
- Any code editor (e.g: VSCode, Atom,... etc)
Terminal commands to start using project:
- Install express and required dependencies
`npm install express body-parser cors`
- Get a copy of the project on your machine
`git clone https://github.com/Aragorn-Elessar/weather-journal-app.git`
- Call into the directory location
`cd weather-journal-app`
- Opens code in
VSCode
`code .`
- Set up
express
environment along with required dependencies
// Require Express to run server and routes
const express = require('express');
// Start up an instance of app
const app = express();
/* Middleware*/
const bodyParser = require('body-parser');
//Here we are configuring express to use body-parser as middle-ware.
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Cors for cross origin allowance
const cors = require('cors');
app.use(cors());
// Initialize the main project folder
app.use(express.static('website'));
- Creat a local server
// Setup Server
port = 3000;
app.listen(port, () => console.log(`Server running on localhost: ${port}`));
- Create
get/post
routes
// Get route
app.get('/all', (req, res) => {
res.send(projectData);
})
// Post route
app.post('/add', (req, res) => {
projectData.date = req.body.date;
projectData.temp = req.body.temp;
projectData.userFeeling = req.body.feelings;
})
- Assign global variables
/* Global Variables */
const baseURL = 'https://api.openweathermap.org/data/2.5/weather?zip=';
const units = '&units=metric';
const apiKey = '&appid=6684c2778e3d4aefc3f8ba10eafc527c';
// Create a new date instance dynamically with JS
let d = new Date();
let newDate = d.getMonth()+1+'.'+ d.getDate()+'.'+ d.getFullYear();
- Create event listener for a
click
ongenerate
button
document.getElementById('generate').addEventListener('click', performAction);
- Add
getWeather
function to grab weather data from the API
// Get weather data
const getWeather = async (URL, zip, unit, key) => {
console.log(URL+zip+unit+key);
const res = await fetch(URL+zip+unit+key);
console.log(res);
try {
const data = await res.json();
console.log(data);
return data;
} catch (e) {
console.log(`error: ${e}`);
}
}
- Add
postData
function to post data to server
// Post data passed in to server
const postData = async (url='', data = {}) => {
await fetch(url, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
try {
console.log(data);
return;
} catch(e) {
console.log(`error: ${e}`);
}
}
- Add
updateUI
function to update user interface with date, temperature and user feeling
// Update user interface
const updateUI = async () => {
const req = await fetch('/all');
try {
const allData = await req.json();
console.log(allData);
document.getElementById('date').innerHTML = allData.date;
document.getElementById('temp').innerHTML = allData.temp;
document.getElementById('content').innerHTML = allData.userFeeling;
} catch(e) {
console.log(`error: ${e}`);
}
}
- Chain the 3 functions together using
.then
// Grab zip code & feeling user entered
function performAction() {
const zipCode = document.getElementById('zip').value;
const feeling = document.getElementById('feelings').value;
// Check if user entered a valid zip to run function chain
if (zipCode && zipCode.length == 5) {
getWeather(baseURL, zipCode, units, apiKey)
.then(data => postData('/add', {
date: newDate,
temp: data.main.temp,
feelings: feeling,
}))
.then(() => updateUI())
} else {
alert('Please, enter a valid zip code');
}
}