2016-12-01 53 views
0

我在一个NodeJs应用程序上工作,该应用程序从FB接收事件并将其放入本地数据库。对于api查询的第一页中的每个事件,除了最后一个之外,这很顺利。节点JS忽略未定义的检查

我收到以下错误:

[December 1st 2016, 1:48:39 pm] TypeError: Cannot read property 'name' of undefined at IncomingMessage. (/home/node/virgo/app.js:217:32) at IncomingMessage.emit (events.js:129:20) at _stream_readable.js:907:16 at process._tickCallback (node.js:372:11)

刚过

console.log(resultBody); 

代码:

function addFBEvent(facebookId){ 
console.log("getting event: " + facebookId); 

var options = { 
    hostname: 'graph.facebook.com', 
    port: 443, 
    path: '/v2.8/'+facebookId+'?fields=name,description,start_time,end_time,place,photos{images}&access_token={INSERT API ACCESS CODE HERE}', 
    method: 'GET' 
}; 

https.request(options, function(res2) { 
    var resultBody = ""; 
    res2.setEncoding('utf8'); 
    res2.on('data', function (chunk) { 
     resultBody = resultBody + chunk; 
    }); 

    res2.on('end', function() { 
     dbConnection = sql.createConnection({ 
           host  : settings.dbHost, 
           user  : settings.dbUser, 
           password : settings.dbPassword 
          }); 

     dbConnection.connect(function(err){ 
       if(!err) { 
        console.log("Database is connected ... nn"); 
       } else { 
        console.log("Error connecting database ... nn"); 
       } 
     }); 

     var json = JSON.parse(resultBody); 

     console.log(resultBody); 

     if (json != undefined){ 
      var eventName = json.name; 
      var eventStart = json.start_time; 
      var eventEnd = json.end_time; 
      var eventDescription = json.description; 
      var eventPlace = json.place.name; 
      var eventPoster = json.photos.data[json.photos.data.length-1].images[0].source; 
      var eventId = json.id; 

      console.log("name: " + eventName + ", start: " + eventStart + ", end: " + eventEnd + ", place: " + eventPlace + ", Poster: " + eventPoster); 
      //console.log("Description: " + eventDescription); 

      dbConnection.query('INSERT INTO SVVirgo.activities(title, description, image, start, end, price, location, facebook) VALUES ("'+eventName+'","'+eventDescription+'","'+eventPoster+'","'+eventStart+'","'+eventEnd+'",0,"'+eventPlace+'","'+eventId+'")', function (err, result){ 

      }); 
     } 

     dbConnection.end(); 
    }) 
}).end(); 
} 

见断裂事件图形API资源管理器:Graph API

事件代码:1682486658666506

我试着赶上,没有运气未定义JSON对象,我也试图验证使用此解决方案的JSON:Stackoverflow validate JSON javascript

+0

我更新了我的答案和更多信息。 – rsp

+0

它正确地检查未定义,但你在这里得到一个错误'var eventPlace = json.place.name;' – tsuz

回答

1

而不是https.request尝试使用request

它会给你解析的JSON,你不必手动去做。

如果你想要做手工像你这样的话,记得在try/catch块包裹var json = JSON.parse(resultBody);(或使用tryjson),因为JSON.parse不能在一个try/catch之外的未知数据使用 - 它可以抛出例外。

另一件事,不要在你的路由处理程序中打开你的数据库连接。您应该打开一次连接,并在处理程序中使用它。有关详情,请参阅this answer

现在要连接到数据库,但你继续连接回调外,让您从var json = JSON.parse(resultBody);数据库连接建立之前开始的所有行。

此外,错误可能并非因为json未定义,而是因为json.place未定义。

你可以改变这一点:

var eventPlace = json.place.name; 

这样:

var eventPlace = json.place && json.place.name; 

您还必须检查json.photos访问json.photos.data和测试之前,如果json.photos.data是一个数组,你把它看作(在你面前可以这样做:

if (json.photos && Array.isArray(json.photos.data)) { 
    // ... 
} 

基本上,你在访问它们之前,需要确保这些值是你想要的值。例如访问该:当json未定义,当json.photos未定义,当json.photos.data未定义,当json.photos.data不是数组,当json.photos.data.length是零,当json.photos.data[json.photos.data.length-1]未定义

json.photos.data[json.photos.data.length-1].images[0].source 

可能会失败,当json.photos.data[json.photos.data.length-1].images未定义,当json.photos.data[json.photos.data.length-1].images不是数组时,当json.photos.data[json.photos.data.length-1].images是数组但是它是空的,或者json.photos.data[json.photos.data.length-1].images是非空数组,但json.photos.data[json.photos.data.length-1].images[0].source未定义。

正如你所看到的,你在这里做了很多假设。当这些假设不符合时,代码将失败。

+0

很多有用的信息谢谢你,幸运的是我可以使用一些关于数据的假设,因为我们是制作在Facebook上的事件。这个不可用的地方是一个异常现象,在未来的事件中不会发生。但是,对于人为错误进行检查可能确实是一件明智的事情。 –