0

I am retriving some data from firebase via observable in valueChanges method.

this.authService.getUser().subscribe(
      user => {
        this.studentDetailsService.readStudentDatabase( user.uid ).subscribe( temp => {
          this.student = temp as StudentDetails ;
        });
      }
    );

but i cant use this.student objects out side the Observable like this

this.authService.getUser().subscribe(
      user => {
        this.studentDetailsService.readStudentDatabase( user.uid ).subscribe( temp => {
          this.student = temp as StudentDetails ;
        });
      }
    );

    this.name = this.student.firstName;

when im doing this console shows this.name is undefined.

how to solve this ?? how can i use those retrived values outside the observable ?

  • 1
    Why do you need to set it outside of subscribe function? – Siddharth Pal Dec 31 '19 at 11:02
  • 1
    Subscribe inside subscribe isn't recommended but anyway you should be able to access it outside since you're storing that in a class property. Make sure temp inside subscribe isn't undefined. – Ramesh Reddy Dec 31 '19 at 11:38
  • So how to do this without subscribe inside subscribe ? – Priyashan Jayasankha Dec 31 '19 at 11:58
  • Use one of the operators that unwraps an observable, e.g. `.pipe(flatMap(...))`. – jonrsharpe Dec 31 '19 at 13:43
  • This has been closed and https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call given as answering this question. While I agree this does touch on the asynchronous aspect, it ignores how to achieve this with Rxjs. This does not answer the question. – Martin Jan 03 '20 at 15:50

1 Answers1

1

You can do something like this

studenDetails$ = this.authService.getUser().pipe(
  switchMap(user => 
     this.studentDetailsService.readStudentDatabase(user.id)));

Then you can output the student details in your template using the async pipe rather than using subscribe.

{{ studenDetails$ | async | json }}

You can do something like the following, but I would recommend using using the above solution instead

this.authService.getUser().pipe(
  switchMap(user => 
     this.studentDetailsService.readStudentDatabase(user.id).pipe(
       tap(student => this.student = student),
       map(student => student.firstName),
       tap(firstName => this.firstName = firstName))).subscribe();

This will set the class field firstName to the students first name.

Martin
  • 15,820
  • 4
  • 47
  • 56