Firebase - извлечение и хранение данных в массиве с обратными вызовами - PullRequest
0 голосов
/ 23 ноября 2018

Я хочу использовать обратные вызовы Firebase для извлечения данных из моей базы данных в реальном времени, сохранения их в массиве, а затем использования этих данных для целей визуализации данных.Но когда я регистрирую консоль для массива, он возвращается пустым.Я ссылался на этот пост , пытаясь понять / исправить мою ошибку, но у меня все еще много проблем.

var genderData=[];
// Get counter values.
function getData(){
    var ref = firebase.database().ref().child('counters');

    return ref.once('value').then((snapshot) => {
        snapshot.forEach((element) => {
            genderData.push(element.val()['Male']);
        });
        return genderData;
    });
}

console.log(genderData);

Моя консоль показывает:

enter image description here

В конце концов, я хочу использовать свой массив для создания диаграммы с библиотекой Chart.js:

// Bar graph displaying the total number of students by gender.
var ctx = document.getElementById("myChart4").getContext('2d');
var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ["Male", "Female", "Non-Binary", "Other", "Unspecified"],
        datasets: [{
            data: genderData,
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)',
            ],
            borderColor: [
                'rgba(255,99,132,1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 206, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
                'rgba(255, 159, 64, 1)'
            ],
            borderWidth: 1
        }]
    },
    options: {
        title: {
            display: true,
            text: 'Total Students by Gender'
        },
        legend:{
            display: false
        },
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero:true
                }
            }]
        }
    }
});

Я былработая над этой проблемой часами, без решения.Все, что я хочу, - это создать простой массив с данными моей базы данных, но у меня было так много проблем.Я действительно надеюсь, что кто-то может помочь мне найти элегантное решение.

РЕДАКТИРОВАТЬ :

Небольшая часть структуры моей базы данных, на всякий случай:

enter image description here enter image description here

1 Ответ

0 голосов
/ 23 ноября 2018

Firebase загружает данные асинхронно.Это означает, что любой код, которому требуется доступ к данным, должен находиться внутри обратного вызова then() или должен использовать собственный обратный вызов then().

При текущем определении getData вы можетепозвоните ему и используйте данные с:

getData().then((data) => {
  console.log("In callback");
  console.log(data);
  console.log(genderData);
})
console.log("Outside callback");
console.log(genderData);

Если вы запустите этот код, вы увидите:

Внешний обратный вызов

[]

Внутренний обратный вызов

[item1, item2, ...]

[item1, item2, ...]

Что следует отметить здесь:

  1. код Outside callback запускается до кода Inside callback, что, вероятно, не то, что вы ожидали.
  2. код за пределами обратного вызова выполняется, массив все еще пуст.Только после выполнения кода внутри обратного вызова массив содержит данные.
  3. внутри обратного вызова genderData и data совпадают.Это потому, что вы return genderData в обратном вызове, который затем всплывает до then() метода.

Окончательное решение для вас состоит в том, что код, который создает диаграмму (где вам нужны данные), должен быть внутри одного из then обратных вызовов, чтобыон вызывается после загрузки данных.Например:

getData().then((data) => {
   var myChart = new Chart(ctx, {
     type: 'bar',
     data: {
        labels: ["Male", "Female", "Non-Binary", "Other", "Unspecified"],
        datasets: [{
            data: data,
            ... 
...