├── .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 | 
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 |
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 |
--------------------------------------------------------------------------------