2017-05-21 1 views
0

Ich versuche, Daten aus meiner Datenbank abzurufen. Mein Code erstellt ein leeres Array und hängt bei jedem Hinzufügen ein untergeordnetes Element an. Es erstellt dann die Liste (ignoriert die MDL-Klassen) und fügt sie dem HTML-Dokument hinzu.Kann Firebase-Snapshot-Daten nicht in Javascript-Array abrufen

<script> 
    // get emergencies to array 
    var firebaseRef = firebase.database().ref('Incidents'); 
    var emergencies = []; 
    // var emergencies = ['Test', 'Test 2', 'Test 3']; 

    firebaseRef.on('child_added', function(snap) { 
     snap.forEach(function (childSnap) { 
      console.log(childSnap.val()); 
      emergencies.push(childSnap.val()); 
     }); 
    }); 

    var opentag = '<ul class="mdl-list" id="emergenciesList">', 
    closetag = '</ul>', 
    array = []; 

    for (i = 1; i <= emergencies.length; i++) { 
     array[i] = '<li class="mdl-list__item">' + emergencies[i] + '</li>'; 
    } 

    var newArray = array.join(" "); 

    document.getElementById('foo').innerHTML = opentag + newArray + closetag; 
</script> 

Das Seltsame ist, dass an der console.log() Anweisung, die Daten werden völlig in Ordnung abgerufen, aber nach der String-Manipulation, ist newArray nicht definiert. Hilfe!

Antwort

1

Das Problem wird durch die Art, wie Sie Ihren Code bestellt haben, verursacht. Die Reihenfolge, in der die Zeilen ausgeführt werden, ist nicht das, was Sie denken. Am einfachsten ist es, das sehen, wenn Sie es so weit zu reduzieren:

var firebaseRef = firebase.database().ref('Incidents'); 

console.log("Before database loading started"); 
firebaseRef.on('child_added', function(snap) { 
    console.log("In child_added"); 
}); 
console.log("After database loading started"); 

Jetzt, in dem die Reihenfolge die Protokollierung geschrieben wird, ist:

Bevor das Laden von Daten

Nach Laden von Daten gestartet

gestartet

In child_added

Dies ist wahrscheinlich nicht das, was Sie erwartet haben. Der Grund für die Protokollierung in dieser Reihenfolge ist, dass Firebase die Daten asynchron lädt. Während also die on('child_added' Zeilen die Daten startet, kann es einige Zeit dauern, um diese Daten von den Firebase-Servern zu erhalten. Anstatt auf die Daten zu warten (was die Interaktion Ihrer Benutzer mit Ihrer App blockieren würde), führt der Browser die Anweisungen nach der Sperre weiterhin aus. Wenn dann die Daten verfügbar sind, ruft sie Ihre Rückruffunktion auf.

Eine gängige Methode, mit der Asynchronität umzugehen, besteht darin, Ihre Probleme neu zu definieren. Im Moment wird Ihr Code geschrieben als "Laden Sie zuerst die Daten und fügen Sie sie dann dem HTML hinzu". Versuchen Sie es stattdessen so zu gestalten, dass Sie "beginnen, die Daten zu laden. Wenn die Daten verfügbar sind, fügen Sie sie dem HTML hinzu". Das übersetzt in diesem Code:

var firebaseRef = firebase.database().ref('Incidents'); 

firebaseRef.on('child_added', function(snapshot) { 
    var ul = document.getElementById("emergenciesList"); 
    if (!ul) { 
     document.getElementById('foo').innerHTML = '<ul class="mdl-list" id="emergenciesList"></ul>'; 
     ul = document.getElementById("emergenciesList"); 
    } 
    var li = document.createElement("li"); 
    li.classList.append("mdl-list__item"); // or: li.className = "mdl-list__item" 
    li.id = snapshot.key; 
    li.innerText = snapshot.val(); 
    ul.appendChild(li); 
}); 

ich die Schleife über den Snapshot entfernt, weil ich nicht sicher bin, es benötigt wird, und es erschwert den Code. Wenn Ihre Datenstruktur die Schleife benötigt, können Sie sie dort hinzufügen, wo sie war.

+0

Vielen Dank! Das macht sehr viel Sinn. Ein Problem jedoch, es funktioniert immer noch nicht; Ich erhalte jetzt einen Fehler, dass "li.classList.append" keine Funktion ist. Ich habe auch "li.className" ausprobiert. Warum das? – wasimsandhu

+0

Interessant. [Element.classList] (https://developer.mozilla.org/en-US/docs/Web/API/Element/classList) a [relativ gut unterstützt] (http://caniuse.com/#feat=classlist) DOM-Methode. Ich fügte eine kompatiblere Alternative in einem Kommentar hinzu. –

Verwandte Themen