2016-09-24 5 views
2

Первое приложение Node/Express.Использование результатов запроса GET в Express-маршрутизаторе

Мне нелегко обернуть голову тем, как извлекать данные из конечной точки и отображать ее в браузере.

У меня есть dataservice.js, который получает объект JSON от конечной точки, как это:

const http = require('http'); 

getFinhockeyData = function() { 

    http.get('http://tilastopalvelu.fi/ih/modules/mod_standings/helper/standings.php?statgroupid=3545', (res) => { 
     console.log(`Got response: ${res.statusCode}`); 

     var body = ""; 

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

     res.on('end', function() { 
     var data = JSON.parse(body); 
     console.log('data parsed.'); 
     console.log('first team name: ' + data.teams[0].TeamName); 
     console.log(typeof data); 
     return data; 
    }) 

    }).on('error', (e) => { 
     console.log(`Got error from Finhockey: ${e.message}`); 
    }); 
} 

module.exports.getFinhockeyData = getFinhockeyData; 

До сих пор все работает и data объект может быть console.logged и его содержание является пригодным для использования.

В router.js выглядит в настоящее время следующим образом:

'use strict'; 

const express = require('express'); 
const async = require('async'); 
const router = express.Router(); 
const dataservice = require('./dataservice.js') 


router.get('/', function(req, res) { 
    async.series([ 
      function(callback) { 
       getFinhockeyData(callback) 
      } 
     ], 
     function(err, results) { 
      console.log('start rendering'); 
      res.render('index', { data: data }); 
     }) 
}); 

module.exports = router; 

Когда я запустить приложение и обновить/маршрут, я могу видеть из консоли, что getFinhockeyData называется и содержание объекта данных доступен в dataservice.js console.logs, но окно браузера зависает, и часть res.render никогда не будет достигнута.

Я понимаю, что рендеринг должен выполняться только после завершения запроса данных о конечных точках (использование async.series), но мне кажется, что мне не хватает фундаментального понимания того, как фактически использовать данные результата из функции getFinhockeyData в основной маршрут.

Любые советы по этому вопросу? Я буду рад предоставить дополнительную информацию, если это необходимо.

ответ

1

Во-первых, выполнение запроса является асинхронным, поэтому вам придется использовать либо обратный вызов, либо обещание.
Даже асинхронная промежуточный слой не позволит вам просто возвращать данные из асинхронного вызова, он требует обратного вызова, но с использованием собственных обещаний кажется проще здесь

const http = require('http'); 

getFinhockeyData = function() { 
    return new Promise((resolve, reject) => { 
    http.get('http://tilastopalvelu.fi/ih/modules/mod_standings/helper/standings.php?statgroupid=3545', (res) => { 
     var body = ""; 

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

     res.on('end', function() { 
     resolve(JSON.parse(body)); 
     }); 

    }).on('error', reject); 
    }); 
} 

module.exports.getFinhockeyData = getFinhockeyData; 

Также обратите внимание, что вы экспортировал модуль с недвижимость

module.exports.getFinhockeyData = getFinhockeyData; 

, когда вы собираетесь использовать, что на маршрутах, вы должны использовать свойство

const dataservice = require('./dataservice.js'); 

router.get('/', function(req, res) { 
    dataservice.getFinhockeyData().then(function(data) { 
     res.render('index', { data: JSON.stringify(data) }); 
    }).catch(function(err) { 
     // epic fail, handle error here 
    }); 
}); 
+0

Это похоже на работу. Большое спасибо! Теперь я перейду к борьбе с шаблонами Мопса. –

0

вы находитесь отвечая на ваш маршрут с помощью

res.render('index', { data: data }); 

Но нет никакой переменной данных. Он должен быть

res.render('index', { data: results }); 

Какого переменный, где вы храните ваши данные, когда речь идет от обратного вызова

0

Причина res.render() не называется это запросы HTTP являются асинхронными. Для того, чтобы получить ответ обратного вызова должен быть передан, который вы сделали, но забыл назвать его в dataservice.js

Это должно помочь ...

Изменить ваши dataservice.js как следующее ...

const http = require('http'); 

getFinhockeyData = function(callback) { 

    http.get('http://tilastopalvelu.fi/ih/modules/mod_standings/helper/standings.php?statgroupid=3545', (res) => { 
     console.log(`Got response: ${res.statusCode}`); 

     var body = ""; 

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

     res.on('end', function() { 
     var data = JSON.parse(body); 
     console.log('data parsed.'); 
     console.log('first team name: ' + data.teams[0].TeamName); 
     console.log(typeof data); 
     callback(null, data); //returning the data to the callback 
    }) 

    }).on('error', (e) => { 
     console.log(`Got error from Finhockey: ${e.message}`); 
     callback(e, null); 
    }); 
} 

module.exports.getFinhockeyData = getFinhockeyData; 

Измените свой маршрутизатор.js ...

router.get('/', function(req, res) { 
    async.series([ 
      function(callback) { 
       getFinhockeyData(callback) 
      } 
     ], 
     function(err, results) { 
     if(err === null){ 
      console.log('start rendering'); 
      res.render('index', { data: results[0] }); 
     } 
     }) 
});