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

feat: support Angular 14 #25353

Closed
3 tasks done
lincolnthree opened this issue May 25, 2022 · 33 comments
Closed
3 tasks done

feat: support Angular 14 #25353

lincolnthree opened this issue May 25, 2022 · 33 comments
Assignees
Labels
package: angular @ionic/angular package type: feature request a new feature, enhancement, or improvement

Comments

@lincolnthree
Copy link

lincolnthree commented May 25, 2022

Prerequisites

Describe the Feature Request

In Angular 14, there is a breaking change that removes the deprecated ComponentFactoryResolver, specifically from router outlets. Since @ionic/angular currently uses this to in ion-router-outlet, Angular applications using Ionic will stop working once upgraded to version 14. Ionic will need to update to support the next version of Angular (currently in RC).

Describe the Use Case

Allow users to continue staying current with Angular releases.

Describe Preferred Solution

Remove references to deprecated resolvers. But whatever you think is best :)

From Angular upgrade guide:

Remove the resolver from RouterOutletContract.activateWith function and the resolver from OutletContext class since factory resolvers are no longer needed.

Describe Alternatives

Unknown.

Related Code

No response

Additional Information

Link to Angular deprecation info:
https://angular.io/api/core/ComponentFactoryResolver#description

Angular v14 Upgrade Guide:
https://update.angular.io/?l=3&v=13.0-14.0

Stack trace:

E/Capacitor/Console: File: http://localhost/polyfills.js - Line 1349 - Msg: Uncaught Error: Uncaught (in promise): TypeError: resolver.resolveComponentFactory is not a function
    TypeError: resolver.resolveComponentFactory is not a function
        at IonRouterOutlet.activateWith (http://localhost/vendor.js:31027:32)
        at ActivateRoutes.activateRoutes (http://localhost/vendor.js:170835:28)
        at http://localhost/vendor.js:170779:12
        at Array.forEach (<anonymous>)
        at ActivateRoutes.activateChildRoutes (http://localhost/vendor.js:170778:25)
        at ActivateRoutes.activateRoutes (http://localhost/vendor.js:170842:14)
        at http://localhost/vendor.js:170779:12
        at Array.forEach (<anonymous>)
        at ActivateRoutes.activateChildRoutes (http://localhost/vendor.js:170778:25)
        at ActivateRoutes.activateRoutes (http://localhost/vendor.js:170842:14)
        at http://localhost/vendor.js:170779:12
        at Array.forEach (<anonymous>)
        at ActivateRoutes.activateChildRoutes (http://localhost/vendor.js:170778:25)
        at ActivateRoutes.activate (http://localhost/vendor.js:170679:10)
        at http://localhost/vendor.js:170662:99
E/Capacitor/Console: File: http://localhost/ - Line 344 - Msg: Uncaught TypeError: Converting circular structure to JSON
        --> starting at object with constructor 'Zone'
        |     property '_zoneDelegate' -> object with constructor '_ZoneDelegate'
        --- property 'zone' closes the circle
E/Capacitor/Console: File: http://localhost/polyfills.js - Line 1349 - Msg: Uncaught Error: Uncaught (in promise): TypeError: resolver.resolveComponentFactory is not a function
    TypeError: resolver.resolveComponentFactory is not a function
        at IonRouterOutlet.activateWith (http://localhost/vendor.js:31027:32)
        at ActivateRoutes.activateRoutes (http://localhost/vendor.js:170835:28)
        at http://localhost/vendor.js:170779:12
        at Array.forEach (<anonymous>)
        at ActivateRoutes.activateChildRoutes (http://localhost/vendor.js:170778:25)
        at ActivateRoutes.activateRoutes (http://localhost/vendor.js:170842:14)
        at http://localhost/vendor.js:170779:12
        at Array.forEach (<anonymous>)
        at ActivateRoutes.activateChildRoutes (http://localhost/vendor.js:170778:25)
        at ActivateRoutes.activateRoutes (http://localhost/vendor.js:170842:14)
        at http://localhost/vendor.js:170779:12
        at Array.forEach (<anonymous>)
        at ActivateRoutes.activateChildRoutes (http://localhost/vendor.js:170778:25)
        at ActivateRoutes.activate (http://localhost/vendor.js:170679:10)
        at http://localhost/vendor.js:170662:99
E/Capacitor/Console: File: http://localhost/ - Line 344 - Msg: Uncaught TypeError: Converting circular structure to JSON
        --> starting at object with constructor 'Zone'
        |     property '_zoneDelegate' -> object with constructor '_ZoneDelegate'
        --- property 'zone' closes the circle

Ionic Info:

mshark:topdecked-unified-patch lincoln$ ionic info

Ionic:

   Ionic CLI                     : 6.19.0 (/Users/lincoln/.nvm/versions/node/v14.19.0/lib/node_modules/@ionic/cli)
   Ionic Framework               : @ionic/angular 6.1.1
   @angular-devkit/build-angular : 14.0.0-rc.1
   @angular-devkit/schematics    : 14.0.0-rc.1
   @angular/cli                  : 14.0.0-rc.1
   @ionic/angular-toolkit        : 6.1.0

Capacitor:

   Capacitor CLI      : 3.5.1
   @capacitor/android : 3.5.1
   @capacitor/core    : 3.5.1
   @capacitor/ios     : 3.5.1

Utility:

   cordova-res : not installed globally
   native-run  : 1.6.0

System:

   NodeJS : v14.19.0 (/Users/lincoln/.nvm/versions/node/v14.19.0/bin/node)
   npm    : 6.14.16
   OS     : macOS Monterey

@ionitron-bot ionitron-bot bot added the triage label May 25, 2022
@sean-perkins sean-perkins self-assigned this May 25, 2022
@sean-perkins
Copy link
Contributor

Thanks for reporting this! Angular 14 is on my radar for Thursday/Friday to deep dive through the upgrade process/changes and validate compatibility with Ionic. Appreciate any issues/findings you run into 👍

@lincolnthree
Copy link
Author

lincolnthree commented May 26, 2022

Awesome! My pleasure, @sean-perkins. So far this is the only issue I've been able to identify because (to my knowledge) it blocks pretty much everything else the v14 update would bring in. That said... if you get a nightly/dev build out I'm happy to try it and report findings.

I have a very large, high complexity app that I am using Ionic/Angular, and I like to stay on the bleeding edge ;)

@liamdebeasi liamdebeasi added type: feature request a new feature, enhancement, or improvement package: angular @ionic/angular package labels May 26, 2022
@ionitron-bot ionitron-bot bot removed the triage label May 26, 2022
@sean-perkins
Copy link
Contributor

@lincolnthree here is a dev-build to test with: 6.1.7-dev.11653587516.10a1f435.

With regards to the component factory resolver, there are 3 primary areas within Ionic effected:

  1. Routing
  2. Modals (overlays)
  3. Popovers (overlays)

Angular 14 introduces a new injector called EnvironmentInjector that we use in-place of component factory resolver (with a slightly different API). In the dev build, I tried to account for backwards support, but believe I will need to configure the dependencies different in the final version, so that this doesn't have to wait until Ionic v7.

Appreciate any issues you discover 👍

@lincolnthree
Copy link
Author

lincolnthree commented May 26, 2022

Thanks @sean-perkins ! I have been able to give it a rough try. So far mostly so good. Everything seems to compile, navigation works, and I haven't noticed any glaring issues.

One thing with modals seems a bit weird:

<ion-modal> must be used inside ion-content.
printRequiredElementError @ index-9ac92660.js:31
printIonContentErrorMsg @ index-b0116568.js:93
initSwipeToClose @ ion-modal.entry.js:1294
(anonymous) @ ion-modal.entry.js:1255
asyncGeneratorStep @ asyncToGenerator.js:3
_next @ asyncToGenerator.js:25
invoke @ zone.js:372
onInvoke @ core.mjs:26356
invoke @ zone.js:371
run @ zone.js:134
(anonymous) @ zone.js:1275
invokeTask @ zone.js:406
onInvokeTask @ core.mjs:26343
invokeTask @ zone.js:405
runTask @ zone.js:178
drainMicroTaskQueue @ zone.js:585
Promise.then (async)
nativeScheduleMicroTask @ zone.js:561
scheduleMicroTask @ zone.js:572
scheduleTask @ zone.js:396
onScheduleTask @ zone.js:283
scheduleTask @ zone.js:386
scheduleTask @ zone.js:221
scheduleMicroTask @ zone.js:241
scheduleResolveOrReject @ zone.js:1265
resolvePromise @ zone.js:1202
(anonymous) @ zone.js:1118
onFinish.oneTimeCallback @ animation-36c1d77d.js:883
(anonymous) @ animation-36c1d77d.js:550
afterAnimation @ animation-36c1d77d.js:549
animationFinish @ animation-36c1d77d.js:565
animationFinish @ animation-36c1d77d.js:567
webAnimations.<computed>.onfinish @ animation-36c1d77d.js:613

Though I'm not sure if this is related. When swipeToClose is enabled, and a modal is instantiated at the class level. There seems to be some issue. (See error above.)

I don't know if this is related, but I haven't been able to try 6.1.7 yet because I've been on Angular 14 next for a while. It's new to me updating from 6.1.1.

The net effect is that the modal works fine, but swipeToClose does not function. Actually swipeToClose doesn't seem to be working on any modals, but I'm guessing that's probably due to some other change.

@lincolnthree
Copy link
Author

lincolnthree commented May 26, 2022

The weird thing is that the error is displayed for some modals and not for others, and all of them are created the same way using ModalController to dynamically spin up the component. Again, swipeToClose does not ever appear to be in a working state.

(I haven't yet tried any of the inline/template modal stuff that's new in 6.1.x)

@lincolnthree
Copy link
Author

Okay, that modal issue seems unrelated. I did some digging and it looks like things have changed (in a breaking way) between Ionic 6.1.1 and 6.1.7.

@lincolnthree
Copy link
Author

Opened a separate issue for that: #25362

@lincolnthree
Copy link
Author

Did some more testing today. I really don't see any issues with this. It seems to be working very well!

@dimitarmar
Copy link

dimitarmar commented May 31, 2022

Hi , @sean-perkins is the fix its only included in the 6.1.7-dev.11653587516.10a1f435 or also part of the 6.1.8 for example, as I have tried but seems work only with tihs particular build

@sean-perkins
Copy link
Contributor

@dimitarmar dev-builds that are created as part of an issue are only included in the following release, when the issue is closed and the associated PR (if there is one), is merged.

With this specific change, the dev-build has not been merged into the main branch, so it will be unavailable in new releases of Ionic Framework.

Due to the nature of the Angular 14 upgrade; it requires more work to backwards support < 14 version of Angular with Ionic, without causing a breaking change.

@lincolnthree
Copy link
Author

@sean-perkins Anything else I can do to help?

@sean-perkins
Copy link
Contributor

@lincolnthree nothing at the moment, appreciate it though! I will likely share a new dev build once I have looked into the backwards compatibility, so that devs can confirm that their apps continue to work before upgrading to Angular 14.

@sean-perkins
Copy link
Contributor

Note: There appears to be an issue with lazy-loading standalone components on routes.

Developers/users will get an exception:

TypeError: undefined is not an object (evaluating 'type[NG_COMP_DEF]') getComponentDef

Need to explore more of the new features in Angular 14.

@lincolnthree
Copy link
Author

@sean-perkins Interesting. What kind of route configuration is required to get that to occur? I haven't seen that.

@danielehrhardt

This comment was marked as duplicate.

@lincolnthree
Copy link
Author

@danielehrhardt Is there something new you're trying to highlight with this stack trace? It appears to be the same one I have in my original issue description.

@Eraldo

This comment was marked as duplicate.

@sean-perkins
Copy link
Contributor

@lincolnthree it should occur when taking advantage of lazy loading a component on a route, instead of lazy loading a module (with a routing module).

For example:

export const routes: Routes = [
  {
    path: '',
    loadComponent: () =>
      import('./pages/landing/landing.page').then((m) => m.LandingPage),
  }
];

This is likely related to standalone components, which may also be problematic at the moment.

Members that are posting stacktraces without a description of your problem or how it differs from the original reported issue's trace will be marked off topic or as a duplicate. Let's please read the thread before just posting, thanks!

@Eraldo
Copy link

Eraldo commented Jun 3, 2022

Ever since I upgraded to angular 14.
Ionic does not start anymore (ng serve).

PS: I did not create any standalone components.

ERROR Error: Uncaught (in promise): TypeError: resolver.resolveComponentFactory is not a function
TypeError: resolver.resolveComponentFactory is not a function
    at IonRouterOutlet.activateWith (ionic-angular.js:3381:38)
    at ActivateRoutes.activateRoutes (router.mjs:2758:40)
    at router.mjs:2706:18
    at Array.forEach (<anonymous>)
    at ActivateRoutes.activateChildRoutes (router.mjs:2705:29)
    at ActivateRoutes.activateRoutes (router.mjs:2765:22)
    at router.mjs:2706:18
    at Array.forEach (<anonymous>)
    at ActivateRoutes.activateChildRoutes (router.mjs:2705:29)
    at ActivateRoutes.activate (router.mjs:2619:14)
    at resolvePromise (zone.js:1211:31)
    at resolvePromise (zone.js:1165:17)
    at zone.js:1278:17
    at _ZoneDelegate.invokeTask (zone.js:406:31)
    at Object.onInvokeTask (core.mjs:26466:33)
    at _ZoneDelegate.invokeTask (zone.js:405:60)
    at Zone.runTask (zone.js:178:47)
    at drainMicroTaskQueue (zone.js:585:35)

@sean-perkins
Copy link
Contributor

@Eraldo is your application using the dev-build: 6.1.7-dev.11653587516.10a1f435?

The current public release of Ionic (6.1.8) is not compatible with Angular 14.

@Eraldo
Copy link

Eraldo commented Jun 3, 2022

@Eraldo is your application using the dev-build: 6.1.7-dev.11653587516.10a1f435?

The current public release of Ionic (6.1.8) is not compatible with Angular 14.

Using: ^6.1.9-dev.11654203961.1dc8c64c

@sean-perkins
Copy link
Contributor

The fix that addresses adding support for Angular 14 is only available in 6.1.7-dev.11653587516.10a1f435. Our dev builds are associated to specific commits. They are only targeted to include the changes of the PR or issue they are posted on. Any other dev build or release tag of Ionic Angular, will not include the fix at this time.

@Eraldo
Copy link

Eraldo commented Jun 3, 2022

6.1.7-dev.11653587516.10a1f435
Also tried 6.1.7-dev.11653587516.10a1f435 now. Same type error. 🤷🏽‍♂️

@rafaelbatistamarcilio
Copy link

Hello.

I dont know if this is an option for everyone, but changing from ion-router-outlet to angular router-outlet it works.

I just need to map de content id in every ion-content, because im using ion-menu.

@lincolnthree
Copy link
Author

@sean-perkins It looks like Angular 14 was officially released today. Any chance you could upload a quick new dev build based off of the latest Ionic version?

@lincolnthree
Copy link
Author

@Eraldo Have you updated both @ionic/angular and @ionic/core? Did you make sure your are using a fixed version in package.json ? e.g. not ~ or ^

@sean-perkins
Copy link
Contributor

@lincolnthree I am still actively working on a build that is backwards compatible with Angular 13 and supporting the upgrade to Angular 14. I'll share a dev build when that is available. I do not believe standalone components will be supported in our first release to allow Angular 14 dependencies.

@rafaelbatistamarcilio Changing from ion-router-outlet to router-outlet is not recommend. You are sacrificing desired UX of native page transitions and perceived app performance when routing. You are better to stay on Angular 13 in the interim.

@Eraldo When testing with dev-builds and Angular, remember to delete the ./angular cache folder. Otherwise Angular will not rebuild your project with the latest dependency changes.

@lincolnthree
Copy link
Author

@sean-perkins Gotcha. That sounds good. Sorry it's so complicated! This deprecation was easy for us where we use the resolvers, but it would not be easy trying to support both APIs at once :( Not sure the Angular team had a great plan for that scenario based on how this change was brought through. Then again, it is a major version bump.

I'm still not sure what standalone components are, but... it sounds like we aren't using them :)

Anyway, looking forward to it :) Thanks for all your hard work!

@sean-perkins
Copy link
Contributor

Here's an updated build that should work on both your Angular 13 projects and work after updating the project to Angular 14:

6.1.9-dev.11654275237.1b595be3

Note: Delete the ./angular cache folder and the running Angular App and re-start the dev server after installing.

Also note: Not all new Angular 14 features are currently supported.

The tricky thing with libraries supporting multiple major versions of a dependency, is how that dependency is configured. We unfortunately cannot update our own dependencies to Angular 14, otherwise the Angular CLI will not build apps on < 14 and using Ionic, which is not desired.

We also want to add support for the new features that Angular has included, but many of those new features are new providers/classes/etc. that are not available in the peer dependency that we are required to install. We typically support the current major version and the previous major version for each major version of Ionic. So for instance, v6 of Ionic supports v12 and v13 of Angular. This isn't a hard rule of thumb, but we are discussing the tradeoffs of only supporting Angular 14+ for Ionic 7.

Standalone components are a "dev preview" feature of Angular 14, that allows you to create a component without declaring/exporting it from an NgModule. This also allows you to have Angular routes that lazy load a component, instead of a whole module. The goal of that feature was to lower the burden of creating modules and the learning curve for new devs in the eco-system. The benefits of the feature to established applications that use SCAM (single component angular modules) or similar, is minimal.

@Eraldo
Copy link

Eraldo commented Jun 3, 2022

@sean-perkins Thank you! 🙏
Quick feedback: I upgraded to 6.1.9-dev.11654275237.1b595be3 and it works nicely now with angular 14. 👍
As I am not keen on some specific features and am very happy with that solution. 😉
Thanks for providing it that quickly. 🥳

@DutchKevv
Copy link

DutchKevv commented Jun 3, 2022

Same problem,

@sean-perkins package version works, I can confirm.

Update @ionic/angular version to 6.1.9-dev.11654275237.1b595be3,
re-run npm install and it all works again..

Any notes on when this is gonna work in stable release? (like to be on-the-edge).

Thanks guys!

@sean-perkins
Copy link
Contributor

The fix has been merged and will be available as part of this week's release (6.1.9).

Thanks!

@ionitron-bot
Copy link

ionitron-bot bot commented Jul 7, 2022

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.

@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators Jul 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
package: angular @ionic/angular package type: feature request a new feature, enhancement, or improvement
Projects
None yet
Development

No branches or pull requests

8 participants