0
votes

I am trying to return all fields from a document from Firebase cloud Firestore. The problem arises when I wish to store this document as an array on my page for use. In whatever instance I try I cannot seem to be able to take the array outside of the .subscribe() method. outside of the subscribe the array is undefined. I assume I am not understanding a process in typescript.

quiz.service.ts

 export interface Quiz{
 q1: string;
 q2: string;
 q3: string;
 q4: string;

 }
 @Injectable({
   providedIn: 'root'
 })
 export class QuizService {
   quizss: Quiz[];
   quiz: Quiz;
   private quizCollection: AngularFirestoreCollection<Quiz>;
   private quizs: Observable<Quiz[]>;

   constructor(db: AngularFirestore) {
     this.quizCollection = db.collection<Quiz>('quiz');

     this.quizs = this.quizCollection.snapshotChanges().pipe(
       map(actions =>{
           return actions.map(a => {
             const data = a.payload.doc.data();
             const id = a.payload.doc.id;
             return{ id, ...data};
           });
       })
     );
    }

   getQuiz(id){
     return this.quizCollection.doc<Quiz>(id).valueChanges().pipe(
       map(response => response)
     );
   }
 }

I get undefined with the following at the console.log in ngOnInit:

 ngOnInit() {
     this.route.queryParams.subscribe((res) => {
       id = res.name;
     });
     answerNumber= 0;
     this.question2 = this.quizService.getQuiz(id);
     console.log("question pull "+ this.question2[0]);  
 }
 returnQuiz( answerNumber) {
     this.quizService.getQuiz(id)
       .subscribe(res =>{
       this.quiz = res;
       let newPoint = {
         q1: this.quiz.q1,
         q2: this.quiz.q2,
         q3: this.quiz.q3,
         q4: this.quiz.q4,
       }
       this.question1[0] = newPoint.q1;
       this.question1[1] = newPoint.q2;
       this.question1[2] = newPoint.q3;
       this.question1[3] = newPoint.q4;

       return this.question1;
     });
  }

I have also tried this with the same error on the console log returning undefined:

 ngOnInit() {
     this.route.queryParams.subscribe((res) => {
       id = res.name;
     });
     answerNumber= 0;
     this.quizService.getQuiz(id)
       .subscribe(res =>{
       this.quiz = res;
       let newPoint = {
         q1: this.quiz.q1,
         q2: this.quiz.q2,
         q3: this.quiz.q3,
         q4: this.quiz.q4,
       }
       this.question1[0] = newPoint.q1;
       this.question1[1] = newPoint.q2;
       this.question1[2] = newPoint.q3;
       this.question1[3] = newPoint.q4;
     });
      console.log("question pull "+ this.question1[0]);
 }
1

1 Answers

0
votes

this is because of asynchronous behavior. console.log is out of subscribe that's why console.log execute before setting value of this.question1 move console.log in side subscribe method. like this

`
ngOnInit() {
    this.route.queryParams.subscribe((res) => {
        id = res.name;
        answerNumber= 0;
        this.quizService.getQuiz(id)
        .subscribe(res =>{
            this.quiz = res;
            let newPoint = {
               q1: this.quiz.q1,
                 q2: this.quiz.q2,
                 q3: this.quiz.q3,
                 q4: this.quiz.q4,
               }
               this.question1[0] = newPoint.q1;
               this.question1[1] = newPoint.q2;
               this.question1[2] = newPoint.q3;
               this.question1[3] = newPoint.q4;
               console.log("question pull "+ this.question1[0]);
           });
         });
     }`