krakenjs / post-robot

Cross domain post-messaging on the client side using a simple listener/client pattern.
Apache License 2.0
741 stars 92 forks source link

postRobot.send block Angular Material 7 change detection #79

Closed ricklang closed 4 years ago

ricklang commented 5 years ago

I have a method to get cross domain data

public getLoginStaff(): Observable<LoginStaff> {
    return from(
        postRobot.send(
          this.win,
          'read',
          { key: StorageKey.loginStaff },
          { timeout: 5000 }
        )
      ).pipe(
        map(({ data }) => data.result),
        catchError(() => null)
      );
  }

I use this method in an Angular 7 route resolver. There is no error for the application and the data is retrieved. But somehow the Angular Material change detection seems to stop working (at least, it seems to need to trigger the change detection somehow). If I change above method to use some other observables, everything works fine. For example, if I just return a static observable, it is fine.

public getLoginStaff(): Observable<LoginStaff> {
    return of({
        staffId: 1234,
        userName: 'john@abc.com',
        phone: '222-444-1999'
      });

I tried to use promise as return for the method, but the problem is the same.

If I don't use Angular Material components, for example just plain html input element, everything works fine.

Do you have any idea what the problem(s) might be? Does ZalgoPromise have anything special?

kwiniarski97 commented 4 years ago

Have you found any workaround for this problem?

kwiniarski97 commented 4 years ago

Ok it looks like I have found a workaround for this. It would be nice if this fixes it for somebody else as well.

So basically the problem is that the library run outside the ngZone. For me only solution have been to import it in a lazy manner and doing it in ngZone.run so it would look something like this:

Instead of:

import * as postRobot from 'post-robot/dist/post-robot';

@Injectable({
...

do something like this:

this.ngZone.run(async () => {
      const postRobot = import('post-robot/dist/post-robot');
      this.postRobot = await postRobot;
      });
bluepnume commented 4 years ago

Awesome, glad it works now.