2017-07-27 11 views
0

私はFirebaseデータベースから読み込んでオブジェクトの配列を作成する関数を持っています。変数keyを定義しましたが、まだ使用できません。変数が定義されていないという参照エラー

var usersList = []; 

const ref = firebase.database().ref() 

function fetchUsers() { 

    ref.child('users').once('value').then(snap => { 
     var promises = []; 

     snap.forEach(childSnap => { 

      var key = childSnap.key 

      promises.push 
       (ref.child(`users/${key}/points`).once('value') 
      ); 


     }); 

     return Promise.all(promises); 

    }).then(function(snapshots) { 
     return snapshots.map(snapper => { 
     var points = snapper.val() 
     return {uid: key, points: points}; 
     }) 
    }).then(function(usersList) { 
     console.log(usersList) 
    }) 

} 

そして、これは私が取得エラーです...

(node:11724) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): ReferenceError: key is not defined 

私はちょうど行う場合:key = childSnap.keyは、その後、すべてのオブジェクトのuidは同じです。

+0

';'が必要な箇所を深く学ぶことを強くお勧めします。 (これは非常に単純です:ステートメントに付けられたブロックで終わらないすべてのステートメントの終わりです。 'x = function(){};'の後に、ステートメントではなく式にアタッチされているので、 'for (ブロックがステートメントに付加されているため、(...){} ')、JavaScriptを使用するかどうか、あるいはJavaScriptに組み込まれている「自動セミコロン挿入」エラー修正メカニズムに頼ることができます。上記では、あなたは半分を供給しており、半分はASIに依存しています。 –

+0

また、 'function'関数が必要とされない' function'関数よりも、矢印関数を優先して使用することを常にお勧めします。 –

答えて

1

keyは、forEachコールバック内でのみ定義されます。もちろん、2番目のthenコールバックから参照することはできません。さらに、それはkeyでしょうか?最初のエントリ?二番目?三番?

代わりに、あなたが値を持つキーを返却する必要があります。私たちはonceからの結果を変換している、上記の最初の行で**

function fetchUsers() { 
    ref.child('users').once('value').then(snap => { 
     var promises = []; 
     snap.forEach(childSnap => { 
      var key = childSnap.key; 
      promises.push(
       ref.child(`users/${key}/points`).once('value').then(
        snapper => ({key, snapper}) // ** 
       ) 
      ); 
     }); 

     return Promise.all(promises); 
    }).then(function(snapshots) { 
     return snapshots.map(({key, snapper}) => { // ** 
      var points = snapper.val(); 
      return {uid: key, points: points}; 
     }); 
    }).then(function(usersList) { 
     console.log(usersList); 
    }); 
} 

ので、それがキーと「スナッパーの両方を持つオブジェクトを返します。 "

2番目の**行では、これらのオブジェクトを個別のkeyおよびsnapperのパラメータとして受け取るために、非構造化パラメータを使用しています。


あなたが積極的に簡潔な矢印を使用したい場合FWIWは、:

function fetchUsers() { 
    ref.child('users').once('value').then(snap => 
     Promise.all(snap.map(childSnap => { 
      const key = childSnap.key; 
      return ref.child(`users/${key}/points`) 
         .once('value') 
         .then(snapper => ({key, snapper})); 
     })) 
    ).then(snapshots => 
     snapshots.map(({key, snapper}) => ({uid: key, points: snapper.val()})) 
    ).then(usersList => { 
     console.log(usersList); 
    }); 
} 

も、むしろ配列を宣言し、forEachコールバックからそれにプッシュするよりもmapの使用を注意してください。 :-)

+1

ありがとう!私はあなたの提案を考慮に入れます。 –

関連する問題