-1

This is my JS code from my router, I'm running a Node Express server with Pug.

var express = require('express');
var router = express.Router();
var https = require('https');

/* GET home page. */
router.get('/', function(req, res, next) {
    var url = 'https://data.police.uk/api/forces';
    var data = [];

    https.get(url, function(res){
        var body = '';

        res.on('data', function(chunk){
            body += chunk;
        });

        res.on('end', function(){
            var response = JSON.parse(body)
            for (var i = 0; i< response.length; i++)
                for (var id in response[i]) {
                    data[i] = response[i]
                }
            console.log(data[0].id);
        });

    }).on('error', function(e){
        console.log("Error: ", e);
    })

    res.render('map', {
        title: 'data[0].id'
    });
});

module.exports = router;

And this is my Pug file to be rendered

p Welcome to #{title}

The console.log in 'res.on()' works perfectly fine and shows the JSON package I was expecting. When I call this array in res.render() i.e. title: 'data[0].name' it throws an undefined error.

gandreadis
  • 3,004
  • 2
  • 26
  • 38
  • You're calling `render` before `data` is ever populated. – Evan Trimboli Sep 14 '17 at 05:49
  • You're aware that all of this is asynchronous? `data` will be empty at the time you call `res.render`. – Zeta Sep 14 '17 at 05:50
  • 1
    Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Rajesh Sep 14 '17 at 05:54

1 Answers1

0

Move your res.render into the area where data is actually populated:

var express = require('express');
var router = express.Router();
var https = require('https');

/* GET home page. */
router.get('/', function(req, res, next) {
    var url = 'https://data.police.uk/api/forces';
    var data = [];

    https.get(url, function(res){
        var body = '';

        res.on('data', function(chunk){
            body += chunk;
        });

        res.on('end', function(){
            var response = JSON.parse(body)
            for (var i = 0; i< response.length; i++)
                for (var id in response[i]) {
                    data[i] = response[i]
                }
            console.log(data[0].id);
            res.render('map', {
                title: 'data[0].id'
            });
        });

    }).on('error', function(e){
        console.log("Error: ", e);
    })

});

module.exports = router;

It's not populated everywhere, that's not how asynchronous code or scoping works.

ryanpcmcquen
  • 6,285
  • 3
  • 24
  • 37