I've spent the day diving into RxJS with Angular2, as the practice of modeling user interfaces as streams is new to me.
I'm experimenting with a user service that provides a stream of User objects. The first User
object will be provided when the user is authenticated. Additional User
Objects may be provided when the User is updated, e.g. they update their profile. If the user is not logged when the application loads, or they logout, then null
is emitted.
As such, an observer implementation in a component would look like this:
export class AppComponent {
private user: User;
private showLoginForm: boolean;
constructor(public userService: UserService) { }
ngOnInit() {
this.userService.user$.subscribe(user => {
this.user = user;
this.showLoginForm = this.user ? false : true;
})
}
}
The userService.user$
observable is a BehaviorSubject
type. Is this how you would implement this? The idea of sending null
, to a stream that expects a User
object, isn't sitting right with me. But at the same time, it does provide a convenient way to answer the question: is the User available or not?
"Going reactive" really needs to be an all-or-nothing thing, IMO. This is a really good recent article on this topic in general.
With regard to Angular2 apps specifically, what this means is that you want to model things as streams everywhere, from end to end - from the HTTP responses that deliver data to the templates used to display it.
So in your case, rather than:
you'd want to do something like:
The key thing to note here is you're modeling your application state as a stream all the way from the service (which presumably is relaying an observable API response) to the component to the template, where you leverage
AsyncPipe
to let angular deal with all the dirtywork of subscribing and updating the UI to reflect changes as needed.In response to @MarkRajcok's comment:
No, and that's actually an important point. The beauty of
AsyncPipe
is that you don't have to manually subscribe to anything, just let Angular do it for you. This sidesteps a minefield of potential change-detection problems that can arise from handling these things manually.Not necessarily. Observable.catch() is quite useful for these purposes:
That being said, my message here isn't that it's never necessary to manually subscribe to things (of course there are situations when it is) but rather, that we should avoid doing it wherever possible. And the more comfortable I get with rx, the rarer I realize those situations are.