2017-07-27 4 views
0

So habe ich eine Funktion, die aus der Firebase-Datenbank liest und dann ein Array von Objekten erstellt. Ich habe Variable key definiert, aber es ist immer noch nicht verfügbar.Referenzfehler, sagt Variable ist nicht definiert

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) 
    }) 

} 

Und das ist der Fehler, den ich bekomme ...

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

Wenn ich nur tun: key = childSnap.key, dann uid jedes Objekt ist das gleiche.

+0

Ich empfehle dringend zu lernen, in der Tiefe, wo ';' erforderlich ist. (Es ist sehr einfach: Am Ende jeder Anweisung nicht durch einen an die Anweisung angehängten Block beendet. Also nach 'x = function() {}; 'weil der Block an den Ausdruck angehängt ist, nicht an die Anweisung, nicht nach' for (...) {} 'weil der Block an die Anweisung angehängt ist.) Dann können Sie eine fundierte Entscheidung treffen, ob Sie sie verwenden oder sich auf den in JavaScript eingebauten" automatischen Semikolon einfügen "Fehlerkorrekturmechanismus verlassen wollen. In den obigen Ausführungen liefern Sie sie zur Hälfte und verlassen sich dabei auf ASI. –

+0

Es wird auch empfohlen, Pfeilfunktionen immer dann zu bevorzugen, wenn eine 'Funktion'-Funktion nicht benötigt wird. –

Antwort

1

key wird nur im Callback forEach definiert. Natürlich können Sie es dann nicht innerhalb des zweiten Callbacks referenzieren. Außerdem, welche key wäre es? Für den ersten Eintrag? Der Zweite? Dritte?

Stattdessen müssen Sie den Schlüssel mit dem Wert zurückzukehren:

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); 
    }); 
} 

Auf der ersten ** Linie oben, sind wir das Ergebnis von once Transformation so gibt es ein Objekt sowohl mit dem Schlüssel und „Schnapper ".

In der zweiten Zeile ** verwenden wir destrukturierte Parameter, um diese Objekte als eindeutige key und snapper Parameter zu empfangen.


FWIW, wenn Sie aggressiv prägnante Pfeile verwenden möchten:

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); 
    }); 
} 

Auch die Verwendung von map beachten Sie, anstatt ein Array deklarieren und es von einem forEach Rückruf drücken. :-)

+1

Vielen Dank! Ich nehme Ihre Vorschläge in Betracht. –

Verwandte Themen