9

This is not a duplicate of this for several reasons. 1. I am using angular 7 not angular 2. 2. I am using rxjs6 not rxjs5. I have no benefit in learning these earlier versions as they are extinct. 3. I am asking about an Observable(boolean) concept when this question does not mention Observable(boolean)

I created an Observable value that I want true/false from it. Here is my code in nav.component.ts file

export class NavComponent implements OnInit {
  private $loggedin: Observable<boolean>;

  constructor( private auth: AuthenticationService){}
  ngOnInit() {
    this.$loggedin = this.auth.$isLoggedinSource;
    console.log('am i logged in ', this.$loggedin);
  }

The console output is :

am i logged in Observable {_isScalar: false, source: BehaviorSubject}
               source: BehaviorSubject {_isScalar: false, observers: 
               Array(0), closed: false, isStopped: false, hasError: 
               false, …}
               _isScalar: false ...

How can I get a boolean, true/false value out of $loggedin?

StackOverflowUser
  • 945
  • 12
  • 10
Lee9287
  • 367
  • 3
  • 6
  • 18
  • There is no relation between rxjs library and angular. Your question is totally addressed in the duplicate flag. if `$isLoggedinSource` is a BehaviorSubject as your tag suggest it, then you just can get the value `this.auth.$isLoggedinSource.getValue();` – Florian Jan 17 '19 at 13:48
  • Florian, I am not using angular2 nor rxjs5 in my app. I have not desire to learn this outdated technology. I am on the cutting edge with angular 7 and rxjs6. This is my first app. The question is two years old. A lifetime in software development. BehaviorSubject is not mentioned in that question. – Lee9287 Jan 17 '19 at 13:54
  • `1.` rxjs is just a library, rxjs6 replaced rxjs5, however your question doesn't address a feature specific of rxjs6. `2.` your question has two tags: `angular` and `behaviorsubject`, so yes, BehaviorSubject is mentioned here. – Florian Jan 17 '19 at 13:59
  • BehaviorSubject is NOT mentioned in the question you are referring to. I got an outstanding state of the art answer on this question. I am happy. I hope another person finds this current answer useful too. – Lee9287 Jan 17 '19 at 14:02

4 Answers4

13

There are two ways that you can use to unwrap the value of an Observable.

  1. By using the async pipe in your Template:

    <p>Am I logged In: {{ $isLoggedinSource | async }}</p>

OR

  1. By subscribeing to the Observable in your Component:

import { Subscription } from 'rxjs';

...

subscription: Subscription;

...

this.subscription = this.$loggedin
  .subscribe(data => console.log('am i logged in ', data));

...

ngOnDestroy() {
  this.subscription.unsubscribe();
}

Which one to use?

If this $loggedin Observable is recurring, and you use the Approach 2, then you'll have to assign it to a Subscription typed property and then call unsubscribe on it inside the ngOnDestroy.

With first approach, you aren't really required to do that.

SiddAjmera
  • 38,129
  • 5
  • 72
  • 110
  • SiddAjmera, Thank you for the outstanding answer. I never even thought of using ngOnDestroy(). It is necessary for memory leaks I think. I totally understand the second approach, implemented it and it works! – Lee9287 Jan 17 '19 at 14:00
  • In a similar project I've tried to implement the `async` method, it gives another error: `"Type boolean | null is not assigneble to type boolean"` (Using angular 15, rxjs 7.8) Also found the answer here: https://stackoverflow.com/a/61781052/2489730 – Beast Feb 28 '23 at 14:02
2

You have to subscribe to it. Right now you are logging the Observable object itself, but what you have to do is subscribe to it so when it is resolved your subscription will listen to it and then print whatever it is resolving.

Richard Ev
  • 52,939
  • 59
  • 191
  • 278
2

If you don't wanna subscribe, you can get the observable value using async and await, but to do this, you have to converte the Observable into a `Promise.

Something like this:

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  public loggedin: boolean;
  public otherValue: boolean;

  constructor(private auth: AuthenticationService) { }

  async ngOnInit() {
    this.loggedin = await this.auth.$isLoggedinSource.toPromise();
    this.otherValue = await this.auth.$otherObservable.toPromise();
  }
}

You can see it working in this stackblitz link.

Thomaz Capra
  • 985
  • 9
  • 21
1

You have to subscribe to observables to get the data.

this.$loggedin.subscribe((data: boolean) => 
{
    console.log('am i logged in ', data);
}
Richard Ev
  • 52,939
  • 59
  • 191
  • 278
RahulAnnae
  • 23
  • 7
  • 1
    You're not required to set the `data` parameter's type as a `boolean`. This should already be done for you when you casted `Observable` to a union type of `boolean`. – Edric Jan 17 '19 at 13:52