Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement BehaviorSubject with getter and setter in Angular 2

I'm trying to implement in my LoginService a isLoggedIn boolean value of type BehaviorSubject together with getter and setter functions to get the value as an Observable / set the variable correctly via its BehaviorSubject. This is working, however it throws two errors in TSLint about "Type not assignable" and "Dublicate identifier". What would be the right way to define it without TSLint complaining about.

This is a stripped down version of the above mentioned code:

@Injectable()
export class LoginService {
  public isLoggedInSource = new BehaviorSubject<boolean>(false);
  public isLoggedIn: Observable<boolean> = this.isLoggedInSource.asObservable(); // Duplicate identifier 'isLoggedIn'.

  constructor(private http: Http) {}

  set isLoggedIn(logged): void { // Duplicate identifier 'isLoggedIn'.
    this.isLoggedInSource.next(logged);
  }

  get isLoggedIn(): Observable<boolean> { // Duplicate identifier 'isLoggedIn'.
    return this.isLoggedInSource.asObservable();
  }

  logout() {
    this.isLoggedIn = false; // Type 'boolean' is not assignable to type 'Observable<boolean>'.
  }

  login(body) {
    return this.http.post('/login', body)
        .map(res => {
                if (res.token) {
                  this.isLoggedIn = true; // Type 'boolean' is not assignable to type 'Observable<boolean>'.
                }
                return res;
              })
        .catch(err => Observable.throw(err););
  }
}
like image 378
Marcello di Simone Avatar asked Oct 07 '16 10:10

Marcello di Simone


1 Answers

When you use TypeScript getter/setter, you have to rename your property, so the property name should be different from getters/setters name.

Moreover, you can modify your code by setting your behaviorSubject as a private member of your service, and just expose your Observable.

@Injectable()
export class LoginService {

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

  public _isLoggedIn: Observable<boolean> = this.isLoggedInSource.asObservable();

  constructor() {}

  set isLoggedIn(logged: boolean) {
    this.isLoggedInSource.next(logged);
  }

  get isLoggedIn() {
    return this._isLoggedIn;
  }

  logout() {
    this.isLoggedIn = false;
  }

  login() {
    this.isLoggedIn = true;
  }

} 

And you will be able to listen change in your component :

export class App {
  constructor(private loginService: LoginService) {

    loginService.isLoggedIn.subscribe(bool => console.log(bool));

    //Wait and simulate a login
    setTimeout(() => {
      loginService.login();
    }, 1200);

  }
}
like image 142
Paul Boutes Avatar answered Sep 20 '22 11:09

Paul Boutes