javascript - Array from firebase database call logs correct data but length shows 0
问题描述
I am making a call to the database and grabbing each of the map items from an array and storing them in an array that I am returning. The array shows the correct data if I log to the console but the array seems to be empty when I try to reference any of the data and the length of the array is also zero.
$(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;
};
Expecting to be able to call the populateTable function but the object isnt created correctly because the array is empty.
解决方案
Problem is db.collection returns a promise, and the data is not yet available when you log it.
you can try a couple of things here:
Move your set state into the listener, if you only care about the React state
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;
};
Another thing you can do is to use an async/await function, but probably to update the state is enough for your case :)
If you browser support it.
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>');
};
});
});
推荐阅读
- ios - Swift - 是否有“具有重复键的字典”解决方法?
- r - qqplot 与直方图的对数正态分布
- spring - Spring MVC 什么时候应该使用 Scope("prototype")?
- laravel - Laravel 迁移无限循环
- python - 1 行(所有数据)到 10 行拆分数据到熊猫库中的数据框
- python - 在 Python 中从 PDF 中提取文本时出现 UnicodeEncodeError
- html - ejs编译错误
- html - 如何在 Bootstrap 4 中将此表单居中?
- etl - CDC 映射的实现不是使用映射变量。
- java - 通过从 JAVA 开始的 C++ 应用程序运行 Shell 脚本