1

I'm currently working with an Angular 8 application that acts as a UI layer on top of an iframe for showing enhanced information to the user. The Angular application will show different angular components based on events triggered from within the iframe:

  • Show a tool-tip (angular component) where the user right-clicked inside the iframe
  • Change the UI attributes of a component when the user clicks on a certain part of the iframe
  • ...

The problem I'm currently facing is that Angular shows/updates the changes in the UI but after more than 30 seconds and sometimes even just ignores the UI updates and the changes are not visible in the UI.

However, if I run just the exact code but using an Angular button click event as trigger of the event, everything just goes fine.

The following is a snippet on how I create the listener to the events coming from the iframe:

this.iframe = document.getElementById('iframe') as any; let canv = this.iframe.contentDocument.getElementById('canv'); canv.addEventListener('contextmenu', (event) => this.onContextMenuEvent(event)) 

As part of the code of the onContextMenuEvent I just calculate some coordinates for positioning a tool-tip and then enable the component with a boolean flag. The following is how the tool-tip component is referenced inside the app.component.html:

<app-tooltip *ngIf="isTooltipShown" [offsetX]="tooltipOffsetX" [offsetY]="tooltipOffsetY" </app-tooltip> 

As I indicated this problem does not occur if the code of the onContextMenuEvent is triggered from an Angular UI element.

As a hint, the stack trace when the problem appears is pretty short just two lines:

eevOnContextMenuEvent (app.component.ts:597) (anonymous)(app.component.ts:394) 

Whereas the other case is pretty long with lots of Angular calls in the middle:

fakeTooltip (app.component.ts:566) (anonymous) (app.component.ngfactory.js.pre-build-optimizer.js:68) handleEvent (core.js.pre-build-optimizer.js:43993) callWithDebugContext (core.js.pre-build-optimizer.js:45632) debugHandleEvent (core.js.pre-build-optimizer.js:45247) dispatchEvent (core.js.pre-build-optimizer.js:29804) (anonymous) (core.js.pre-build-optimizer.js:31837) schedulerFn (core.js.pre-build-optimizer.js:35379) __tryOrUnsub (Subscriber.js.pre-build-optimizer.js:185) next (Subscriber.js.pre-build-optimizer.js:124) _next (Subscriber.js.pre-build-optimizer.js:72) next (Subscriber.js.pre-build-optimizer.js:49) next (Subject.js.pre-build-optimizer.js:39) emit (core.js.pre-build-optimizer.js:35298) resetSchematics (hideable-panel.component.ts:230) (anonymous) (hideable-panel.component.ngfactory.js.pre-build-optimizer.js:50) handleEvent (core.js.pre-build-optimizer.js:43993) callWithDebugContext (core.js.pre-build-optimizer.js:45632) debugHandleEvent (core.js.pre-build-optimizer.js:45247) dispatchEvent (core.js.pre-build-optimizer.js:29804) (anonymous) (core.js.pre-build-optimizer.js:42925) (anonymous) (platform-browser.js.pre-build-optimizer.js:2668) invokeTask (zone-evergreen.js.pre-build-optimizer.js:391) onInvokeTask (core.js.pre-build-optimizer.js:39680) invokeTask (zone-evergreen.js.pre-build-optimizer.js:390) runTask (zone-evergreen.js.pre-build-optimizer.js:168) invokeTask (zone-evergreen.js.pre-build-optimizer.js:465) invokeTask (zone-evergreen.js.pre-build-optimizer.js:1603) globalZoneAwareCallback (zone-evergreen.js.pre-build-optimizer.js:1629) 

Any hints on how to solve this issue?

Thanks in advance.

Edit 1: As required on the comments I share part of the code of the onContextMenuEvent (unfortunately I cannot share the actual code):

onContextMenuEvent(mouseEvent: any): void { var param = this.getEventParameters(mouseEvent); this.tooltipOffsetX = param.x; this.tooltipOffsetY = param.y; ... this.isTooltipShown = true; } 

Another hint is that the method ngOnChanges on the tool-tip component gets called not immediately but after more that 30 seconds (it's not constant).

2
  • Can you please show how onContextMenuEvent looks like? Commented Nov 18, 2019 at 13:50
  • @akash the question has been updated Commented Nov 18, 2019 at 14:43

1 Answer 1

2

It may happen that the Angular somehow lost its 'zone'.

Try to import the zone in your contructor with

constructor( private zone: NgZone ) { ... } 

and run the onContextMenuEvent inside the zone:

onContextMenuEvent(mouseEvent: any): void { this.zone.run(() => { var param = this.getEventParameters(mouseEvent); this.tooltipOffsetX = param.x; this.tooltipOffsetY = param.y; ... this.isTooltipShown = true; }) } 

might be enough to wrap the this.isTooltipShown = true; inside the zone

Sign up to request clarification or add additional context in comments.

1 Comment

Great answer. After testing your proposal everything works fine. Thanks!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.