Skip to main content
Post Closed as "Duplicate" by Günter Zöchbauer, toskv, CommunityBot
added 905 characters in body
Source Link
Jason Goemaat
  • 29.3k
  • 15
  • 89
  • 119

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? &nbsp; <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...

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? &nbsp; <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?

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? &nbsp; <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...

Source Link
Jason Goemaat
  • 29.3k
  • 15
  • 89
  • 119

How to trigger change detection in Angular2?

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? &nbsp; <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?