2017-07-06 32 views
0

我想使用谷歌地圖的地方API來構建一個簡單的Web應用程序。現在我只是將從api獲得的數據插入到我的mongodb數據庫中。谷歌地圖API和表達錯誤發送後無法設置標題

谷歌地圖的地方npm模塊@google/maps有一個基於經度和緯度的返回數據的地方法。我試圖實現的是這個

  • 當對api路由發出請求時,它應該檢查數據庫並返回一些數據。
  • 如果數據庫爲空應該查詢谷歌地圖放置數據的API,將其插入數據庫,然後從數據庫執行查找請求。這裏是我的[代碼] [1]中,錯誤的是:

Error: Can't set headers after they are sent. at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:357:11) at ServerResponse.header (C:\Express\pizza\node_modules\express\lib\response.js:730:10) at ServerResponse.send (C:\Express\pizza\node_modules\express\lib\response.js:170:12) at ServerResponse.json (C:\Express\pizza\node_modules\express\lib\response.js:256:15) at sendJsonResponse (C:\Express\pizza\app_api\controllers\locations.js:9:9) at C:\Express\pizza\app_api\controllers\locations.js:73:39 at Query.<anonymous> (C:\Express\pizza\node_modules\mongoose\lib\model.js:3800:16) at C:\Express\pizza\node_modules\kareem\index.js:277:21 at C:\Express\pizza\node_modules\kareem\index.js:131:16 at _combinedTickCallback (internal/process/next_tick.js:73:7) at process._tickCallback (internal/process/next_tick.js:104:9)

是否有更好的方法來解決我的問題,我願意接受建議

var mongoose = require('mongoose'); 
 
var Location = require('../models/locations'); 
 
var googleMapsClient = require('@google/maps').createClient({ 
 
    key: process.env.MAP_API_KEY 
 
}); 
 

 
var sendJsonResponse = function(res, status, content) { 
 
    res.status(status); 
 
    res.json(content); 
 
}; 
 
//function to filter data returned from api 
 
var buildLocations = function(results) { 
 
    results === Array; 
 
    var newList = []; 
 
    var j = 3; 
 
    for (var i = 0; i < j; i++) { 
 
     if (results[i].photos) { 
 

 
      newList.push({ 
 
       place_id: results[i].place_id, 
 
       name: results[i].name, 
 
       rating: results[i].rating, 
 
       address: results[i].formatted_address, 
 
       photos: results[i].photos, 
 
       location: results[i].geometry.location 
 
      }) 
 
     } 
 
    } 
 
    return newList 
 
} 
 

 

 
//function to save data to database from api 
 
var saveToDbFromApi = function(locations,req,res,callback){ 
 
    for(var i=0; i<locations.length; i++){ 
 
     Location.create({ 
 
      name: locations[i].name 
 
     },function(err,locations){ 
 
      if(err){ 
 
       console.log(err); 
 
      } 
 
      else{ 
 
      callback(req,res); 
 
      } 
 
     }) 
 
    } 
 
} 
 

 

 

 
module.exports.locationList = function(req, res) { 
 
    Location.find({}, function(err, locations) { 
 
     if (err) { 
 
      console.log(err); 
 
      sendJsonResponse(res, 400, err); 
 
     } 
 
     if (!locations.length) { 
 
      googleMapsClient.places({ 
 
       location: [5.526679, -0.48085], 
 
       radius: 50000, 
 
       type: 'restaurant' 
 
      }, function(err, response){ 
 
       if(err){ 
 
        sendJsonResponse(res,400,err); 
 
       } 
 
       else{ 
 
        var locations = buildLocations(response.json.results); 
 
        saveToDbFromApi(locations,req,res,function(req,res){ 
 
         Location.find({},function(err,locations){ 
 
          if(err){ 
 
          console.log(err) 
 
          } 
 
          else{ 
 
\t \t \t \t \t \t \t //this line brings up the 'cant set headers after they are sent error' 
 
          return sendJsonResponse(res,200,locations); 
 
          } 
 
         }) 
 
        }); 
 
       } 
 
      }) 
 
      
 
     } else { 
 
      sendJsonResponse(res, 200, locations); 
 
     } 
 
    }) 
 

 
}

+1

您正在嘗試將數據發佈到已關閉的響應。我們可以看到你的代碼嗎?單獨的堆棧跟蹤將無濟於事。我們需要查看進行調用的服務器端代碼。 – magreenberg

+0

我發佈了一個代碼鏈接,你可以在這裏查看[鏈接] https://pastebin.com/bCEepQ1Z –

回答

1

問題來自saveToDbFromApi函數。您正在遍歷名爲位置的列表,將每個位置添加到數據庫中;但是,在添加每個位置之後,您正在運行callback(req,res);您只希望在將所有位置保存到數據庫後運行一次回調。

這是你的。

//function to save data to database from api 
var saveToDbFromApi = function(locations,req,res,callback){ 
    for(var i=0; i<locations.length; i++){ 
     Location.create({ 
      name: locations[i].name 
     },function(err,locations){ 
      if(err){ 
       console.log(err); 
      } 
      else{ 
       // this runs the callback on each iteration 
       // you need to run the callback once 
       callback(req,res); 

      } 
     }) 
    } 
} 

這是我推薦的。

//function to save data to database from api 
var saveToDbFromApi = function(locations,req,res,callback){ 

    // you might want to validate the locations is an array and has a length 
    // for now we will skip of this to show you a solution 

    // use a self calling recursive function 
    (function saveLocation(i){ 

     Location.create({ 
      name: locations[i].name 
     }, function(err,locations){ 

      // throw errors if any 
      if(err){ 
       return console.error(err); 
      } 

      // check if we have another location to save 
      // if we do, use the recursive function to save the next one 
      // if not run the callback 
      if(i<locations.length){ 
       saveLocation(i+1); 
      } else{ 
       callback(req,res); 
      } 

     }); 

    })(0); 

} 
+0

感謝錯誤消失,但它只返回一個位置,而不是三個:( –

+0

我需要看看什麼在'var Location = require('../ models/locations')裏面進行''Location.find({})'的回調處理'sendJsonResponse()'調用,這會返回數據 – magreenberg

+0

這裏是'../ models/locations'文件的內容[https://pastebin.com/AhsCcPEJ] –

0

注意

if (err) { 
     console.log(err); 
     sendJsonResponse(res, 400, err); 
    } 

如果錯了,它發送一個響應,但沒有一個retun,這樣你就可以達到您的評論線和嘗試重新發送頭。

相關問題