I'm creating a Facebook service that calls the Facebook javascript api and am wondering how to best implement change detection when my values are updated.
I have a UserService
which has a currentUser
property that is a BehaviorSubject:
currentUser: Subject<User> = new BehaviorSubject<User>(new User(null));
And when I want to update the user in response to the facebook javascript sdk telling me the user has logged in or logged out, I update that and need to call tick()
on an ApplicationRef
:
updateUser(user: User) {
console.log('UserService.updateUser:', user);
this.currentUser.next(user);
this.appRef.tick(); // UI does not update without this
}
constructor(facebook: Facebook) {
this.facebook.facebookEvents.filter(x => x != null
&& x.eventName == 'auth.authResponseChange')
.subscribe((event) => {
this.updateUser(new User(event.data));
}
}
In my component I store the 'currentUser' from the user service in the constructor and bind to the value property:
<h2>Logged into Facebook as {{currentUser.value.name}}</h2>
<p>Is this you? <img src="{{currentUser.value.profilePicUrl}}"></p>
Am I doing something wrong? Is there a better way than having to call ApplicationRef.tick() after a change triggered from an external library?
Edit
I tried using NgZone and that doesn't work, using a different event that returns posts in a feed as the service pages through them:
constructor(userService: UserService, private ref: ApplicationRef, private zone: NgZone)
...
this.postsSubject.subscribe((post) => {
this.zone.runOutsideAngular(() => { // doesn't do anything
this.posts.push(post);
console.log('postsSubject POST, count is ', this.posts.length);
ref.tick(); // required to update bindings
});
}
The console shows the count incrementing, but the html binding {{posts.length}}
is only updated if I add the ref.tick()
call...
I think I saw somewhere that you can make available 'inputs' to any component from the top-level app component which might be the way to go for the logged in user, but not other calls like getting posts in a feed...
{{ (currentUser | async)?.value?.name}}
. – Verlinevermeer