Patrick M.
Patrick M.

Reputation: 819

How should I use BehaviorSubject class from a Service in the HTML Template of a Component in Angular 4?

I have a service used for Authentication that exposes a user of class BehaviorSubject. I want to use the service in a Component to allow login/logout and display user properties.... Nothing really new there.

I know I could subscribe to the user object in the component and assign the result to a local object, which in turn I would use in the view. But I'm interested in knowing how to use it without subscribing in typescript, but directly in the html, thanks to the async pipe, I guess.

These are the pseudo class I would use:

The Auth Service

export class User {
    id: string;
    username: string;
    gender: string;

    constructor( some params...) {
        // set all the attributes...
    }
}


@Injectable()
export class AuthService {

    private _currentUser: BehaviorSubject<User> = new BehaviorSubject(null);
    get currentUser() {
        // do some logic here if needed
        return this._currentUser;
    }

    constructor() {}

    login(email, password)  {
        DoSomeHttpRequestToLogin()
        .then( userParams => {
            const user = new User(userParams);
            this._currentUser.next(user);
            })
        .catch(error => {});
    }   
}

The Component

@Component({
    selector: 'app-main',
    templateUrl: './main.component.html'
})
export class MainComponent implements OnInit {

    notWhatIWantToUse_User: User;
    currentUser$: ????

    constructor( private _authService: AuthService ) {

        // With subscription, which I'd like to avoid
        this.authService.currentUser.subscribe( user => {
            this.notWhatIWantToUse_User = user;
        }

        // Without subscription, my goal
        this.currentUser = this.authService.currentUser;
    }   

    ngOnInit() {
        this.authService.login();
    }
}

main.component.html

<h1> First Method: Hello {{ notWhatIWantToUse_User?.username }} </h1>  <!-- this works -->
<h1> Second Method: Hello {{ ... some code with currentUser$ to show username, or id or gender... }} </h1>

Thanks for the help

Upvotes: 5

Views: 12966

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 658235

You can use the async pipe to subscribe

First Method: Hello {{ (authService.currentUser | async)?.username }}

This is especially nice if you use ChangeDetectionStrategy.OnPush because the async pipe notifies change detection automatically to run when a new value is emitted.

Upvotes: 21

Related Questions