Массив из журнала вызовов базы данных firebase содержит правильные данные, но длина показывает 0 - PullRequest
0 голосов
/ 01 июня 2019

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

$(document).ready(function(){
    //This ('click','li') binds all dynamically added shit to respond to click.
    $('ul.hiddentext').on('click','li', function(e){
        $(this).siblings().css('font-weight','normal');
        $(this).css('font-weight','bolder');
        let text = $(this).text();
        currentWorkoutSelected = text;
        var exercises = pullWorkoutTableData(text)
        console.log(exercises.length);
        var workout = new workoutTemplate(text, user, exercises);
        workout.populateTable();

        //Populate the title of the workout based on if its already there or not.
        if($('h4#workoutTitle').length == 0){
            $("table.exerciseList").prepend('<h4 id="workoutTitle">'+ text+ '</h4>');
        }
        else{
            $('h4#workoutTitle').replaceWith('<h4 id="workoutTitle">'+ text+ '</h4>');
        };
    });
});

//Taking the data needed for the workout table from the database.
function pullWorkoutTableData(workoutName){
    var exerciseList = [];
    db.collection('workouts').get().then((snapshot)=>{
        snapshot.docs.forEach(doc => {
            if(doc.data().name === workoutName && doc.data().user.includes(user)){
                doc.data().exercises.forEach(element =>{
                    var exercise = [element.name, element.weight, element.reps];
                    exerciseList.push(exercise);
                });
            };
        });
    });
    console.log(exerciseList);
    this.setState({exerciseList});
    return exerciseList;
};

Ожидается возможность вызова функции populateTable, но объект не создан правильно, поскольку массив пуст.

1 Ответ

1 голос
/ 01 июня 2019

Проблема в том, что db.collection возвращает обещание, и данные еще не доступны, когда вы регистрируете его.

Вы можете попробовать пару вещей здесь:

Переместите ваше установленное состояние в слушатель, если вам небезразлично только состояние React

function pullWorkoutTableData(workoutName){
    var exerciseList = [];
    db.collection('workouts').get().then((snapshot)=>{
        snapshot.docs.forEach(doc => {
            if(doc.data().name === workoutName && doc.data().user.includes(user)){
                doc.data().exercises.forEach(element =>{
                    var exercise = [element.name, element.weight, element.reps];
                    exerciseList.push(exercise);
                });
            };
        });
        this.setState({exerciseList}); // <---- HERE
    });

    return exerciseList;
};

Другая вещь, которую вы можете сделать, это использовать функцию async / await, но, вероятно, для обновления достаточно для вашего случая:)

Если ваш браузер поддерживает это.

function pullWorkoutTableData(workoutName){
    var exerciseList = [];
    return db.collection('workouts').get().then((snapshot)=>{
        snapshot.docs.forEach(doc => {
            if(doc.data().name === workoutName && doc.data().user.includes(user)){
                doc.data().exercises.forEach(element =>{
                    var exercise = [element.name, element.weight, element.reps];
                    exerciseList.push(exercise);
                });
            };
        });
        return Promise.resolve({ exerciseList })
    });
};
$(document).ready(async function(){
    //This ('click','li') binds all dynamically added shit to respond to click.
    $('ul.hiddentext').on('click','li', function(e){
        $(this).siblings().css('font-weight','normal');
        $(this).css('font-weight','bolder');
        let text = $(this).text();
        currentWorkoutSelected = text;
        var { exerciseList: exercises } = await pullWorkoutTableData(text)
        console.log(exercises.length);
        var workout = new workoutTemplate(text, user, exercises);
        workout.populateTable();

        //Populate the title of the workout based on if its already there or not.
        if($('h4#workoutTitle').length == 0){
            $("table.exerciseList").prepend('<h4 id="workoutTitle">'+ text+ '</h4>');
        }
        else{
            $('h4#workoutTitle').replaceWith('<h4 id="workoutTitle">'+ text+ '</h4>');
        };
    });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...