/weather-journal-app

An async weather app with updated UI

Primary LanguageJavaScript

Weather-Journal App Project

Table of Contents

Overview

This project require to create an asynchronous web app that uses Web API and user data to dynamically update the UI.

Project-Description

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.

Getting-Started

Prerequisites

  • Install Node.js from official site
  • Any code editor (e.g: VSCode, Atom,... etc)

Installing

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 .`

Steps

Server Side Changes

  • 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;
})

Client Side Changes

  • 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 on generate 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');
    }
}

Author

Mahmoud Gadallah

Credits

A Udacity Nanodegree project, provided by FWD initiative