#javascript #reactjs #google-cloud-firestore
#javascript #reactjs #google-облако-firestore
Вопрос:
У меня есть веб-сайт, где пользователи могут посещать курсы. Когда пользователь начинает курс, я хочу добавить идентификатор курса к документу этого пользователя в firestore. На веб-сайте у пользователя есть своя страница профиля. В одном из разделов есть раздел «Курсы в процессе», где пользователи могут увидеть курс, на который они в данный момент записаны.
Я могу добавить ключ документа курса в поле в документе пользователя, как только они начнут курс, поле представляет собой массив строк, содержащих ключи к документам в другой коллекции.
Проблема, с которой я сталкиваюсь, заключается в попытке отобразить курсы, на которые пользователь в данный момент зарегистрирован, в своем профиле.
Я думаю, проблема в том, что документы курса возвращаются после отображения экрана.
Я пытался использовать async и await, чтобы убедиться, что код сначала завершает цикл и получает весь документ курса, чтобы затем он мог отображать их на экране, но это не работает.
Заранее большое спасибо за любую помощь
getEnrolledCareersList = async () => {
let careersEnrolled = [];
let careersEnrolledTemp = [];
let careersEnrolledDocumentKeys = ["84YU2pLABF6qUvUEuwIm", "kwBaAUwkjTutGTcIKShw"];
await careersEnrolledDocumentKeys.forEach((documentKey) =>{
console.log("documentKey: ", documentKey);
db.collection("...")
.where("courseDocumentKey", "==", documentKey)
.get()
.then(
(querySnapshot) => {
if (querySnapshot.empty) {
// doc.data() will be undefined in this case
console.log("No such document!");
return;
}
querySnapshot.forEach((doc) => {
console.log("getEnrolledCareersList Document data:", doc.data());
const {
courseName,
courseId,
coursePhotoUrl,
courseDocumentKey,
} = doc.data();
careersEnrolledTemp.push({
courseName,
courseId,
coursePhotoUrl,
courseKey: courseDocumentKey,
});
});
},
function(error) {
console.log("Error getting document Error: ", error);
},
);
});
Компонент JSX:
<div
style={{
// border: "solid #8492A6 5px",
display: "flex",
flexDirection: "column",
//flexWrap: "wrap",
justifyContent: "flex-start",
padding: "0 0%",
}}>
{this.state.currentPaths.map((item, index) => (
<div
style={{
display: "flex",
flexDirection: "row",
padding: "1% 1%",
}}>
<img
alt={"career image"}
src={item.coursePhotoUrl}
/>
<div
style={{
// border:"solid red 1px",
display: "flex",
flexDirection: "column",
justifyContent: "space-evenly",
padding: "0 2%",
}}>
{/*Career Name Label*/}
<label
style={{
// border: "solid #8492A6",
textAlign: "center",
}}>
{item.courseName}
</label>
{/*Career Percentage Completed Label*/}
<label
style={{
// border: "solid #8492A6",
textAlign: "center",
}}>
Percentage
</label>
</div>
</div>
))}
</div>
Комментарии:
1. Вы захотите собрать обещания в массив и использовать
Promise.all
, чтобы дождаться их завершения, прежде чем двигаться дальше.
Ответ №1:
В итоге я сделал это, и это решило мою проблему. Друг помог мне получить это, а также большое спасибо @Doug Stevenson.
getCourse = id => db.collection("abc")
.doc(id)
.get();
getEnrolledCareersList = async (courseIds = ["1", "2"]) => {
const requests = courseIds.map(this.getCourse);
const responses = await Promise.all(requests);
const enrolledCourses = responses.map(doc => doc.data());
this.setState({
...this.state,
enrolledCourses,
});
};