├── .gitignore ├── giphy.gif ├── README.md ├── package.json ├── views └── index.ejs ├── server.js └── public └── css └── style.css /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /giphy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmorelli25/simple-nodejs-weather-app/HEAD/giphy.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # simple-nodejs-weather-app 2 | Simple Node.js Command Line Weather Application 3 | 4 | * Check out the **[Live Demo](https://simple-nodejs-weather-app-irhhpddsku.now.sh/)** 5 | * Read the full tutorial on how to build this application at [codeburst.io](https://codeburst.io) 6 | * Run the web app locally: 7 | ``` 8 | node server.js 9 | // Now open your browser and visit: localhost:3000 10 | ``` 11 | ![gif](https://github.com/bmorelli25/simple-nodejs-weather-app/blob/master/giphy.gif?raw=true 'website gif') 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple-nodejs-weather-app", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/bmorelli25/simple-nodejs-weather-app.git" 13 | }, 14 | "author": "brandon morelli", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/bmorelli25/simple-nodejs-weather-app/issues" 18 | }, 19 | "homepage": "https://github.com/bmorelli25/simple-nodejs-weather-app#readme", 20 | "dependencies": { 21 | "body-parser": "^1.17.2", 22 | "express": "^4.15.3", 23 | "request": "^2.81.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Test 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 | 14 | 15 |
16 | <% if(weather !== null){ %> 17 |

<%= weather %>

18 | <% } %> 19 | 20 | <% if(error !== null){ %> 21 |

<%= error %>

22 | <% } %> 23 |
24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const bodyParser = require('body-parser'); 3 | const request = require('request'); 4 | const app = express() 5 | 6 | const apiKey = '*****************'; 7 | 8 | app.use(express.static('public')); 9 | app.use(bodyParser.urlencoded({ extended: true })); 10 | app.set('view engine', 'ejs') 11 | 12 | app.get('/', function (req, res) { 13 | res.render('index', {weather: null, error: null}); 14 | }) 15 | 16 | app.post('/', function (req, res) { 17 | let city = req.body.city; 18 | let url = `http://api.openweathermap.org/data/2.5/weather?q=${city}&units=imperial&appid=${apiKey}` 19 | 20 | request(url, function (err, response, body) { 21 | if(err){ 22 | res.render('index', {weather: null, error: 'Error, please try again'}); 23 | } else { 24 | let weather = JSON.parse(body) 25 | if(weather.main == undefined){ 26 | res.render('index', {weather: null, error: 'Error, please try again'}); 27 | } else { 28 | let weatherText = `It's ${weather.main.temp} degrees in ${weather.name}!`; 29 | res.render('index', {weather: weatherText, error: null}); 30 | } 31 | } 32 | }); 33 | }) 34 | 35 | app.listen(3000, function () { 36 | console.log('Example app listening on port 3000!') 37 | }) 38 | -------------------------------------------------------------------------------- /public/css/style.css: -------------------------------------------------------------------------------- 1 | /* 2 | Styles from this codepen: 3 | https://codepen.io/official_naveen/pen/rgknI 4 | */ 5 | 6 | body { 7 | width: 800px; 8 | margin: 0 auto; 9 | font-family: 'Open Sans', sans-serif; 10 | } 11 | .container { 12 | width: 600px; 13 | margin: 0 auto; 14 | } 15 | fieldset { 16 | display: block; 17 | -webkit-margin-start: 0px; 18 | -webkit-margin-end: 0px; 19 | -webkit-padding-before: 0em; 20 | -webkit-padding-start: 0em; 21 | -webkit-padding-end: 0em; 22 | -webkit-padding-after: 0em; 23 | border: 0px; 24 | border-image-source: initial; 25 | border-image-slice: initial; 26 | border-image-width: initial; 27 | border-image-outset: initial; 28 | border-image-repeat: initial; 29 | min-width: -webkit-min-content; 30 | padding: 30px; 31 | } 32 | .ghost-input, p { 33 | display: block; 34 | font-weight:300; 35 | width: 100%; 36 | font-size: 25px; 37 | border:0px; 38 | outline: none; 39 | width: 100%; 40 | -webkit-box-sizing: border-box; 41 | -moz-box-sizing: border-box; 42 | box-sizing: border-box; 43 | color: #4b545f; 44 | background: #fff; 45 | font-family: Open Sans,Verdana; 46 | padding: 10px 15px; 47 | margin: 30px 0px; 48 | -webkit-transition: all 0.1s ease-in-out; 49 | -moz-transition: all 0.1s ease-in-out; 50 | -ms-transition: all 0.1s ease-in-out; 51 | -o-transition: all 0.1s ease-in-out; 52 | transition: all 0.1s ease-in-out; 53 | } 54 | .ghost-input:focus { 55 | border-bottom:1px solid #ddd; 56 | } 57 | .ghost-button { 58 | background-color: transparent; 59 | border:2px solid #ddd; 60 | padding:10px 30px; 61 | width: 100%; 62 | min-width: 350px; 63 | -webkit-transition: all 0.1s ease-in-out; 64 | -moz-transition: all 0.1s ease-in-out; 65 | -ms-transition: all 0.1s ease-in-out; 66 | -o-transition: all 0.1s ease-in-out; 67 | transition: all 0.1s ease-in-out; 68 | } 69 | .ghost-button:hover { 70 | border:2px solid #515151; 71 | } 72 | p { 73 | color: #E64A19; 74 | } 75 | --------------------------------------------------------------------------------