Ошибка деструктурирования и сокращения свойств

#javascript #node.js #ecmascript-6 #destructuring

#javascript #node.js #ecmascript-6 #деструктурирование

Вопрос:

Я новичок в node, и я работал с деструктурированием. Я хотел получить свойство body из ответа weather-api и деструктурировать его. Код работает нормально, когда я подключен к Интернету, но когда я отключаю Интернет, происходит сбой кода и выдается ошибка.

Вот код, который я написал

 ```const request = require('request')

const geocode = (address, callback)=>{
    const url = "https://api.mapbox.com/geocoding/v5/mapbox.places/"  encodeURIComponent(address)  ".json?access_token=theKeyHere"

    request({url, json: true}, (error, {body})=>{
        if(error){
            callback('Uh! Oh, Unable to connect with location service', undefined )
        } else if (body.features.length ===0 || body.message){
            callback(`Uh! Oh, Can't find location. Try another search`, undefined)
        } else {
            callback(undefined, {
                latitude: body.features[0].center[1],
                longitude: body.features[0].center[0],
                location_Name: body.features[0].place_name
            })
        }
    })
}     ```
  

Ошибка, которую я получаю

     request({url, json: true}, (error, {body={}})=>{
                                        ^

TypeError: Cannot read property 'body' of undefined
    at Request._callback (F:nodejsweatherApputilsgeocode.js:6:41)
    at self.callback (F:nodejsweatherAppnode_modulesrequestrequest.js:185:22)
    at Request.emit (events.js:315:20)
    at Request.onRequestError (F:nodejsweatherAppnode_modulesrequestrequest.js:877:8)
    at ClientRequest.emit (events.js:315:20)
    at TLSSocket.socketErrorListener (_http_client.js:426:9)
    at TLSSocket.emit (events.js:315:20)
    at emitErrorNT (internal/streams/destroy.js:92:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
    at processTicksAndRejections (internal/process/task_queues.js:84:21)
  

Ответ №1:

Проблема в том, что при возникновении ошибки вы все еще пытаетесь уничтожить данные:

 request({url, json: true}, (error, {body={}})=>{
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^
  

Но в случае ошибки данные не поступили, вместо этого вы получили undefined . Вы не можете деструктурировать undefined или null .

У вас есть два варианта:

  1. Используйте обычный параметр, а затем выполните деструктурирование, как только убедитесь, что ошибки нет:

      request({url, json: true}, (error, response)=>{
         if (error) {
             // ...
             return;
         }
         const {body = {}} = response;
         // ...
     });
      
  2. Укажите значение по умолчанию для параметра в целом, а не только body :

      request({url, json: true}, (error, {body={}} = {})=>{
     // −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^
         // ...
     });
      

    Таким образом, если вас пропустят undefined , вместо этого вы будете деструктурировать {} . И поскольку вы уже используете значение по умолчанию body , если оно не существует для объекта, это значение по умолчанию сработает.

Комментарии:

1. я знал, что вы, вероятно, отвечаете на это, поэтому я сначала опубликовал краткий ответ о том, в чем проблема, а затем добавил, как это исправить (чтобы я мог быть первым)! ;p

Ответ №2:

проблема в том, что когда вы не подключены к Интернету или не получаете ожидаемую структуру ответа, вторым аргументом этой функции является undefined . итак, вы, по сути, пытаетесь сделать это:

undefined.body что, конечно, неверно

вы можете сделать 2 вещи, чтобы исправить это:

 // - this will guarantee that the second argument will always default to 
//   an empty object. this way, you will not get an error
(error, { body={} } = {}) => {

  

или

 (error, response) => {
  let body = {};
  if (response) body = response.body || {};
}