0

I am trying to fix my error but I don't know how I can fix it. I have searched arround the internet and tried some solutions like this Node UnhandledPromiseRejectionWarning but I didn't manage to fix it.

This is my error enter image description here

And this is my code

var express = require('express')
var session = require('express-session')
var bodyParser = require('body-parser')
var request = require('request-promise')
var mongoose = require('mongoose')

require('dotenv').config()

mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true })

var citySchema = new mongoose.Schema({
    name: String
})

var cityModel = mongoose.model('City', citySchema)

async function collectWeather(cities) {
    var weatherData = []
    for (var city_object of cities) {
        var city = city_object.name
        var url = `http://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=e`
        request(url)
        var body = await request(url)
        var weatherJSON = JSON.parse(body)
        var weather = {
        city: city,
        temperature: Math.round(weatherJSON.main.temp),
        description: weatherJSON.weather[0].description,
        icon: weatherJSON.weather[0].icon,
        }
        weatherData.push(weather)
    }
    return weatherData
}

express()
    .use(express.static('static'))
    .use(bodyParser.urlencoded({extended: true}))
    .use(session({
        resave: false,
        saveUninitialized: true,
        secret: process.env.SESSION_SECRET
    }))

    .set('view engine', 'ejs')
    .set('views', 'view')

    .get('/', function(req, res) {
        cityModel.find({}, function(err, cities) {
            collectWeather(cities).then(function(result) {
                var weatherData = {weatherData: result}
                res.render('index', weatherData)
            })
        })
    })

    .post('/', function(req, res) {
        var newCity = new cityModel({name: req.body.city_name})
        newCity.save()
        res.redirect('/')
    })

    .listen(4000)

I am still a beginner with node.js.

Thank you in advance.

Rooney
  • 1,674
  • 1
  • 14
  • 24

3 Answers3

1

In addition to Rami's answer, you should fix newCity.save() operation. Mongoose save() return thenables. So you should handle save like this:

post('/', function(req, res) {
    var newCity = new cityModel({name: req.body.city_name})
    newCity.save()
    .then(result => {
        res.redirect('/')
    })
    .catch(err => {
        // handle error
        console.log(err);
        // render an error page for example.
    });  
});
dimitris tseggenes
  • 3,031
  • 2
  • 16
  • 23
1

NodeJS uses asynchronous, non-blocking calls instead of using multiple threads. It does this (at least in part) by using Promises. A Promise is an object that represents something that will finish later.

On the line

        var body = await request(url)

the call request(url) returns a promise, and the use of await causes the rest of the function to be deferred until the promise is resolved.

If the request fails, the Promise is rejected instead. You could handle this case by using the .catch(callback) method of the Promise returned by request(url).

There may be other ways to do this, but I am not aware of them as have not used async/await notation.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await

lowtex
  • 707
  • 4
  • 22
0

You should always catch your promises, you missed that here

collectWeather(cities).then(function(result) {
    var weatherData = {weatherData: result}
    res.render('index', weatherData)
}).catch(err => {

    //res.render('error', err)
})
Rami Jarrar
  • 4,523
  • 7
  • 36
  • 52