1

I'm using a third-party library that requires me to implement my own event listener. This is done by implementing window.onGoogleYoloLoad = function() { ... }. I tried to implement it like this in my user service file:

@Injectable()
export class UserService {
    public userCredentials = new EventEmitter<Credentials>();
    constructor(){
        window.onGoogleYoloLoad = function(credentials){
            this.userCredentials.emit(credentials);
        }
    }
}

Then I subscribed to the event. The subscribers do get notified, but the view does not get updated. It's like angular doesn't know the event happened.

AskYous
  • 4,332
  • 9
  • 46
  • 82

1 Answers1

0

The callback is running outside the Angular zone. Move the callback to a component and call ChangeDetectorRef.detectChanges

import { Component, ChangeDetectorRef } from '@angular/core';

@Component(...)
export class MyComponent {
    public userCredentials = new EventEmitter<Credentials>();
    constructor(
        private cd: ChangeDetectorRef,
        private userService: UserService
    ){
        window.onGoogleYoloLoad = function(credentials){
            this.userService.userCredentials.emit(credentials);
            this.cd.detectChanges();
        }
    }
}

Re-entering the Angular zone is another option: What's the difference between markForCheck() and detectChanges()

import { Injectable, NgZone } from '@angular/core';

@Injectable()
export class UserService {
    public userCredentials = new EventEmitter<Credentials>();
    constructor(private zone: NgZone){
        window.onGoogleYoloLoad = function(credentials){
            this.zone.run(() => {
                this.userCredentials.emit(credentials);
            })
        }
    }
}
hayden
  • 2,643
  • 17
  • 21
  • Ah, that's because you can't inject `ChangeDetectorRef` into a service. Can you move the code to a component? – hayden Jan 05 '18 at 06:59