Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: Angular application (Zone.js) + cordova.js file #2896

Open
AlanRaz opened this issue May 9, 2020 · 3 comments
Open

bug: Angular application (Zone.js) + cordova.js file #2896

AlanRaz opened this issue May 9, 2020 · 3 comments

Comments

@AlanRaz
Copy link

@AlanRaz AlanRaz commented May 9, 2020

Bug Report

This issue can interest also https://github.com/ionic-team/ionic

Capacitor Version

Capacitor 1.x and 2.x

Affected Platform(s)

  • Android
  • iOS
  • Electron
  • Web

Current Behavior

Angular application (with or whithout Ionic Angular) is broken by the "cordova.js" injected in head scripts of index.html. This can create several problem as described in the following issue from the Angular repository.
See: angular/angular#22509

In my case, when I'm in a several "router-oulet" deep and hit the back button, the previous child component will be created but not rendered correctly (no life cycle hooks are called like ngOnInit).

Expected Behavior

In my case, the previous child should be created and rendered correctly (life cycle hooks should be called).

Sample Code or Sample Application Repo

https://github.com/AlanRaz/capacitor-angular-issue

Reproduction Steps

npm i && npm run build && npx cap sync android && npx cap open android

Follow the navigation button (in green) then when you arrive to the step 2, just hit the back button (in red).
You can see that the component are no more rendered correctly and see in the console log that the constructor is called but the ngOnInit are not called.

Other Technical Details

This is also a problem with older Angular versions.
See: angular/angular#22509

Other Information

It took me a while to found this issue because I didn't know that Capacitor added the cordova.js at run time in the header of the index.html.

What we use to do in old Cordova/Angular app to resolve this was to follow (https://github.com/angular/angular/blob/master/packages/zone.js/NON-STANDARD-APIS.md#others) and put the scripts in this order:

<script src="zone.js"></script>
<script src="cordova.js"></script>
<script src="zone-patch-cordova.js"></script>

I don't know witch solutions will be good in termes of design and maintainability.

  • Let, the user to add a workaround like this one in the head of index.html:
<script>
  window.addEventListener = function () {
    (window.EventTarget || Window).prototype.addEventListener.apply(this, arguments);
  };
  window.removeEventListener = function () {
    (window.EventTarget || Window).prototype.removeEventListener.apply(this, arguments);
  };
  document.addEventListener = function () {
    (window.EventTarget || Document).prototype.addEventListener.apply(this, arguments);
  };
  document.removeEventListener = function () {
    (window.EventTarget || Document).prototype.removeEventListener.apply(this, arguments);
  };
</script>

But, I think it's really not explicit for the end-user.

  • Capacitor should inject directly this workaround before injecting cordova.js.
    I don't know if this workaround can have side effect on other web libraries (or other libraries to have the same problem).
@AlanRaz AlanRaz changed the title bug: Angular application + cordova.js file bug: Angular application (Zone.js) + cordova.js file May 9, 2020
@AlanRaz
Copy link
Author

@AlanRaz AlanRaz commented May 28, 2020

Any thoughts on this ?

@dwieeb
Copy link
Member

@dwieeb dwieeb commented Jun 23, 2020

Yes, for Cordova compatibility Capacitor generates a file at the top of <head>. One of the files included is cordova.js if Cordova plugins are detected. I doubt the injected Capacitor scripts need to be at the very top of <head>.

In modern Angular apps, it appears zone.js is bundled into the vendor bundle. cordova.js is usually added manually to <head> in Angular apps, but it appears the bundles are loaded at the bottom of <body>, so how is this not an issue for Angular w/ Cordova?

@AlanRaz
Copy link
Author

@AlanRaz AlanRaz commented Jun 30, 2020

It's also a problem with Angular and Cordova project, what I usually do is changing the import order (but I don't know if it's the correct thing to do to fix this kind of problem).

I'm pretty sure I can reproduce the problem with an Ionic project too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.