2017-05-21 6 views
0

データベースからデータを取得しようとしています。私のコードは、空の配列を作成し、それが追加されるたびにそれに子を追加します。次に、リストを作成し(MDLクラスを無視して)、HTMLドキュメントに追加します。Javascriptアレイにfirebaseのスナップショットデータを取得できません

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

奇妙なことははconsole.log()文で、データは完全に罰金取得されていること、ですが、文字列操作の後、NEWARRAYは未定義です。助けて!

答えて

1

問題は、コードを注文したことが原因です。行が実行される順序は、あなたが考えるものではありません。それはあなたがこれにそれを減らす場合は、これを見るために最も簡単です:

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

今ロギングが書き込まれる順序は次のとおりです。

データベースのロードが開始された後、データベースの負荷が

を開始する前に

子どもに追加

これはおそらくあなたが期待したものではありません。ロギングがこの順に表示されるのは、Firebaseがデータを非同期でロードするためです。したがって、on('child_added'の行がデータをロードするを開始している間に、そのデータをFirebaseサーバから取得するまでに時間がかかることがあります。ユーザーがアプリケーションとやりとりすることを妨げるデータを待つ代わりに、ブラウザはブロックの後のステートメントを実行し続けます。データが利用可能になると、コールバック関数が呼び出されます。

非同期性を扱う一般的な方法は、問題を再構成することです。今すぐあなたのコードは、 "最初にデータを読み込んだ後、HTMLに追加する"と書かれています。代わりに、 "データの読み込みを開始します。データが利用可能な場合は、HTMLに追加してください"というフレーミングを試してください。つまり、このコードに変換します。

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

私はそれが必要とされるかわからない、それはコードを複雑にするので、私は、スナップショットの上にループを削除しました。データ構造にループが必要な場合は、元の場所に戻すことができます。

+0

ありがとうございます!これは多くの意味があります。 1つの問題は、それでも動作しません。私は今、 "li.classList.append"が関数ではないというエラーを受け取っています。私は "li.className"も試みました。何故ですか? – wasimsandhu

+0

興味深い。 [Element.classList](https://developer.mozilla.org/en-US/docs/Web/API/Element/classList)[比較的よくサポートされている](http://caniuse.com/#feat=classlist) DOMメソッド。コメントに互換性のある代替案を追加しました。 –

関連する問題