I'm trying to use Typeform library in my application, but I have a lot problems with it. After loading the js scripts, the Angular zone is wrong and I get this message:
Error: Zone.js has detected that ZoneAwarePromise
(window|global).Promise
has been overwritten. Most likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)
The code of my appponent.ts is:
import { Component, Inject, AfterViewInit} from '@angular/core';
import { DOCUMENT } from '@angular/mon';
import * as typeformEmbed from '@typeform/embed';
@Component({
selector: 'my-app',
template: `<div #my_typeform></div>`,
})
export class AppComponent implements AfterViewInit {
constructor(
@Inject(DOCUMENT) private document: Document
){}
ngAfterViewInit() {
const element = this.document.getElementById.call(document, 'my_typeform');
typeformEmbed.makeWidget(element, '', { onSubmit: () => console.log('Close') });
}
}
I have tried to run manually ngZone to ensure that it's ran inside Angular zone, but didn't work. In this case, appponent.ts was like
import { Component, Inject, AfterViewInit, NgZone} from '@angular/core';
import { DOCUMENT } from '@angular/mon';
import * as typeformEmbed from '@typeform/embed';
@Component({
selector: 'my-app',
template: `<div #my_typeform></div>`,
})
export class AppComponent implements AfterViewInit {
constructor(
@Inject(DOCUMENT) private document: any,
@Inject(NgZone) private ngZone: NgZone
){}
ngAfterViewInit() {
this.ngZone.run(() => {
const element = this.document.getElementById.call(document, 'my_typeform');
typeformEmbed.makeWidget(element, '', { onSubmit: () => console.log('Close') });
});
}
}
I have also tried to import 'zone.js/dist/zone-patch-rxjs' in my polyfill.ts file, but it didn't work either.
You can see a project with the minimal code to reproduce it in
Any clue or help is really wele!
Thanks in advance!
I'm trying to use Typeform library in my application, but I have a lot problems with it. After loading the js scripts, the Angular zone is wrong and I get this message:
Error: Zone.js has detected that ZoneAwarePromise
(window|global).Promise
has been overwritten. Most likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)
The code of my app.ponent.ts is:
import { Component, Inject, AfterViewInit} from '@angular/core';
import { DOCUMENT } from '@angular/mon';
import * as typeformEmbed from '@typeform/embed';
@Component({
selector: 'my-app',
template: `<div #my_typeform></div>`,
})
export class AppComponent implements AfterViewInit {
constructor(
@Inject(DOCUMENT) private document: Document
){}
ngAfterViewInit() {
const element = this.document.getElementById.call(document, 'my_typeform');
typeformEmbed.makeWidget(element, 'https://jonathan.typeform./to/zvlr4L', { onSubmit: () => console.log('Close') });
}
}
I have tried to run manually ngZone to ensure that it's ran inside Angular zone, but didn't work. In this case, app.ponent.ts was like
import { Component, Inject, AfterViewInit, NgZone} from '@angular/core';
import { DOCUMENT } from '@angular/mon';
import * as typeformEmbed from '@typeform/embed';
@Component({
selector: 'my-app',
template: `<div #my_typeform></div>`,
})
export class AppComponent implements AfterViewInit {
constructor(
@Inject(DOCUMENT) private document: any,
@Inject(NgZone) private ngZone: NgZone
){}
ngAfterViewInit() {
this.ngZone.run(() => {
const element = this.document.getElementById.call(document, 'my_typeform');
typeformEmbed.makeWidget(element, 'https://jonathan.typeform./to/zvlr4L', { onSubmit: () => console.log('Close') });
});
}
}
I have also tried to import 'zone.js/dist/zone-patch-rxjs' in my polyfill.ts file, but it didn't work either.
You can see a project with the minimal code to reproduce it in https://stackblitz./edit/angular-issue-repro2-daytbo
Any clue or help is really wele!
Thanks in advance!
Share edited Oct 24, 2019 at 10:23 Tony 20.2k7 gold badges41 silver badges62 bronze badges asked Sep 18, 2019 at 15:25 user2132866user2132866 1112 silver badges6 bronze badges 1- For the moment, the solution is a downgrade (0.7.2) of the external library which doesn't overwrite promises – user2132866 Commented Sep 19, 2019 at 14:48
2 Answers
Reset to default 3For those still looking for a VERY easy fix for this, this is what worked for me.
Step 1) Move your import 'zone/dist/...'
stuff from your polyfill.ts
file to your main.ts
file before your bootstrap.
So in your main.ts
file, you should have something like:
import 'zone.js/dist/zone' // Included with Angular CLI.
platformBrowserDynamic()
.bootstrapModule(AppModule, { ngZone: new NgZone({}) })
And just be sure you've totally removed it from your polyfill.ts
file
Step 2) Profit.
OK, so let me explain what's actually happening (that I noticed):
There's a race condition where occasionally the polyfilled promise gets added AFTER the zone.js
module overrides the native promise. This is what causes Zone to recognize that it's been replaced and throw that error.
This happened regardless of the order in the polyfill.ts
I put the imports in.
I originally tried putting the loader for zone.js
in a timeout with a short timer (100ms). This worked to prevent the error message we're all seeing, but occasionally didn't fire fast enough to load the zone.js
module before hitting the bootstrap.
So obviously this was causing a race condition. (Of my own making.)
The thought then was to make the zone.js
import OFFICIALLY last before loading the bootstrap. I wanted to make sure that was going to work:
I was able to test this by putting a console.log
in the main.ts
and the polyfill.ts
files. What I saw was that the polyfill.ts
is always loaded before the main.ts
.
So placing the import 'zone.js/dist/zone'
line in the main.ts
solves this problem once and for all. Then your polyfill.ts
file is free to pull in and load any modules necessary before getting that zone.js
file imported.
Not sure but you can try this.
Add these into your polyfill
import 'core-js/es6';
import 'core-js/es7/reflect';
import "zone.js/dist/zone";
Few link to try out
https://github./angular/zone.js/issues/465
https://github./angular/angular/issues/31724