Issue with RxJs BehaviorSubject's subscriber not being notified of value change

有些话、适合烂在心里 提交于 2019-11-28 04:15:19

问题


I am trying to use a RxJS BehaviorSubject that contains a boolean representing whether or not a user is connected/logged in the application.

Here is the component that subscribes to the new BehaviorSubject value i.e. true when the user has authenticated:

import {Component, OnInit} from '@angular/core';
import {CollapseDirective} from 'ng2-bootstrap';
import {PublicNavbarComponent} from './public.navbar.component';
import {PrivateNavbarComponent} from './private.navbar.component';
import {SessionService} from '../../session/session.service';

@Component({
    selector: 'navbar',
    templateUrl: 'app/shared/components/navbar.component.html',
    providers: [SessionService],
    directives: [PublicNavbarComponent, PrivateNavbarComponent, CollapseDirective]
})
export class NavbarComponent implements OnInit {

    constructor(private sessionService:SessionService) {
    }

    ngOnInit() {
        this.sessionService.authenticated$.subscribe({
            next: (value)=> this.isAuthenticated = value
        });
    }

    isAuthenticated:boolean = false;

    isCollapsed:boolean = true;
}

Here is the class/service containing the BehaviorSubject:

import {Injectable} from '@angular/core';
import {Http, Headers, RequestOptions} from '@angular/http';
import {Credentials} from '../shared/models/credentials.model';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import 'rxjs/Rx';

@Injectable()
export class SessionService {

    authenticated$:BehaviorSubject<boolean> = new BehaviorSubject(false);
    currentUserAccount;

    constructor(private http:Http) {
    }

    signin(credentials:Credentials) {
        let headers = new Headers({'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'});
        let options = new RequestOptions({headers: headers});
        this.http.post('/api/signin', 'username=' + credentials.username + '&password=' + credentials.password, options)
            .subscribe(response=>
                this.setPersonalInfo(response.headers.get('x-auth-token'))
            );
    }

    setPersonalInfo(sessionToken) {
        localStorage.setItem('authenticated', 'true');
        localStorage.setItem('sessionToken', sessionToken);
        this.authenticated$.next(true);//next() from false to true
        this.http.get('/api/utils/current-useraccount')
            .subscribe(param => this.currentUserAccount = param);
    }
}

However this does not have the expected behavior: it seems that authenticated$ from session service is only true within setPersonalInfo function and isAuthenticated from NavbarComponent isn't notified at all when this.authenticated$.next(true) is invoked.


回答1:


It seems like you have multiple instances of SessionService. e.g. you provided it more than once and the instance that you call signin in is not the same instance as the one you injected in NavbarComponent.

It depends on your project design how you provide your services. Usually session services are singletons.
I recommend removing providers: [SessionService], from NavbarComponent.




回答2:


I usually provide SessionService at bootstrap (and not with providers: []) to make sure you share one global SessionService instance throughout the entire app.

bootstrap(AppComponent,
            [SessionService]);


来源:https://stackoverflow.com/questions/37150891/issue-with-rxjs-behaviorsubjects-subscriber-not-being-notified-of-value-change

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!