Search code examples
angularangular2-observablesbehaviorsubject

Angular: Type 'Observable<boolean>' has no compatible call signatures


I'm still learning angular, and I want to make a service with a boolean observable, and subscribe to that observable.

I followed this tutorial because what I really want is to hide menu nav links when user is not logged in, and this tutorial is nearly the same.

So in my login service:

export class LoginService {

  private loggedIn = new BehaviorSubject<boolean>(false);

  get isLoggedIn() {
    console.log(this.loggedIn);
    return this.loggedIn.asObservable();
  }

  constructor(
    public http: Http,
    public utilsService: UtilsService) { }

  public login(credentials: Credentials): Observable<Response> {
    // login code
    // if user succeed login then:
    this.loggedIn.next(true);
  }

  public logout(): Observable<Response> {
    // logout code
    // if user succeed logout then:
    this.loggedIn.next(false);
  }
}

and in my component I use this function

public isLoggedIn: boolean;

userIsLoggedIn() {

  this._login.isLoggedIn().subscribe(
    ((res: boolean) => {
        console.log(res);
        this.isLoggedIn = res;
    })
  );

}  // <- this is (36,5) position returned from error log

If everything is ok, then using a simple *ngIf="isLoggedIn" in the nav links of the component template it should work. But Something is wrong and I'm getting next error when trying to compile.

ERROR in /project-folder/src/app/shared/navbar/navbar.ts (36,5): Cannot invoke an expression whose type lacks a call signature. Type 'Observable' has no compatible call signatures.

No idea what's wrong. But as a newbie I need to say that I don't know very well what a BehaviorSubject is, and haven't found good and easy to understand documentation about it.

It should be easy, but after a few days trying it without success, i'm near giving up about hiding the links for not logged in users.

EDIT: I add part of the package.json to show the versions used:

"devDependencies": {
  "@angular/cli": "1.4.5",
  "@angular/compiler-cli": "4.4.4",
  "@angular/language-service": "4.4.4",
  "@types/node": "6.0.60",
  "codelyzer": "3.2.0",
  // some of the dependencies omitted
  "gulp": "3.9.1",
  "gulp-coveralls": "0.1.4",
  "typescript": "2.3.3"
}

Solution

  • You define isLoggedIn as a property with this getter:

      get isLoggedIn() {
        console.log(this.loggedIn);
        return this.loggedIn.asObservable();
      }
    

    But then you call it as a function:

      this._login.isLoggedIn().subscribe(
        ((res: boolean) => {
            console.log(res);
            this.isLoggedIn = res;
        })
      );
    

    You need to instead access it as a property:

      this._login.isLoggedIn.subscribe(  // No () here
        ((res: boolean) => {
            console.log(res);
            this.isLoggedIn = res;
        })
      );