Not able to setup ionic v5 + Gestures Issue

I there, I’ve been trying to find any issues about this and I found 1 closed without solution and an other one for react which does not apply to angular I guess.

First the setup issue/problem, although I have globally installed @ionic/angular@5.9.3, when I create a new ionic project the latest version is installed locally.
The questions here would be:

  • Is it possible to start an Ionic project with an angular specific version?
  • Does Ionic 5 works with latest angular dependencies “^13.0.0”?
  • How should I downgrade the ionic framework version to not be limited to +60 chromium android usersdevice browser support? If I change >@ionic/angular within package.json (locally @6.1.2) to version “^5.0.0” or “~5.9.3” or “5.9.3” but gives the following error while trying to execute ionic serve:
[ng] 
[ng] Error: node_modules/ionicons/dist/types/components.d.ts:66:15 - error TS2320: Interface 'HTMLIonIconElement' cannot simultaneously extend types 'IonIcon' and 'HTMLStencilElement'.
[ng]   Named property 'ariaHidden' of types 'IonIcon' and 'HTMLStencilElement' are not identical.
[ng] 
[ng] 66     interface HTMLIonIconElement extends Components.IonIcon, HTMLStencilElement {
[ng]                  ~~~~~~~~~~~~~~~~~~
[ng] 
[ng] 
[ng] Error: node_modules/ionicons/dist/types/components.d.ts:66:15 - error TS2320: Interface 'HTMLIonIconElement' cannot simultaneously extend types 'IonIcon' and 'HTMLStencilElement'.
[ng]   Named property 'ariaLabel' of types 'IonIcon' and 'HTMLStencilElement' are not identical.
[ng] 
[ng] 66     interface HTMLIonIconElement extends Components.IonIcon, HTMLStencilElement {
[ng]                  ~~~~~~~~~~~~~~~~~~
[ng] 
[ng] 
[ng] Error: node_modules/typescript/lib/lib.dom.d.ts:4632:101 - error TS2344: Type 'HTMLElementTagNameMap[K]' does not satisfy the constraint 'Element'.
[ng]   Type 'HTMLElement | HTMLMetaElement | HTMLAnchorElement | HTMLAreaElement | HTMLAudioElement | ... 151 more ... | HTMLMarqueeElement' is not assignable to type 'Element'.
[ng]     Type 'HTMLIonIconElement' is not assignable to type 'Element'.
[ng]       Property 'ariaHidden' is optional in type 'HTMLIonIconElement' but required in type 'Element'.
[ng] 
[ng] 4632     getElementsByTagName<K extends keyof HTMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementTagNameMap[K]>;
[ng]                                                                                                          ~~~~~~~~~~~~~~~~~~~~~~~~
[ng] 
[ng] 
[ng] Error: node_modules/typescript/lib/lib.dom.d.ts:4953:101 - error TS2344: Type 'HTMLElementTagNameMap[K]' does not satisfy the constraint 'Element'.
[ng]   Type 'HTMLElement | HTMLMetaElement | HTMLAnchorElement | HTMLAreaElement | HTMLAudioElement | ... 151 more ... | HTMLMarqueeElement' is not assignable to type 'Element'.
[ng] 
[ng] 4953     getElementsByTagName<K extends keyof HTMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementTagNameMap[K]>;
[ng]                                                                                                          ~~~~~~~~~~~~~~~~~~~~~~~~
[ng] 
[ng] 
[ng] 
[ng] node_modules_ionic_core_dist_esm_focus-visible-f4ad4f1a_js.js      | focus-visible-f4ad4f1a-js                    |   1.99 kB | 
[ng] node_modules_ionic_core_dist_esm_ion-text_entry_js.js              | -                                            |   1.70 kB | 
[ng] 
[ng] Build at: 2022-04-21T12:12:45.332Z - Hash: 83641904bab4306e - Time: 9714ms
[ng] ✖ Failed to compile.
  • NPM listings
  • npm -g list:
    ├── @angular/cli@12.2.17
    ├── @ionic/angular@5.9.3
    ├── @ionic/cli@6.19.0
    ├── corepack@0.10.0
    └── npm@8.6.0

  • npm list:
    ├── ngcc_entry_points.json@ extraneous
    ├── @angular-devkit/build-angular@13.2.6
    ├── @angular-eslint/builder@13.0.1
    ├── @angular-eslint/eslint-plugin-template@13.0.1
    ├── @angular-eslint/eslint-plugin@13.0.1
    ├── @angular-eslint/template-parser@13.0.1
    ├── @angular/cli@13.2.6
    ├── @angular/common@13.2.7
    ├── @angular/compiler-cli@13.2.7
    ├── @angular/compiler@13.2.7
    ├── @angular/core@13.2.7
    ├── @angular/forms@13.2.7
    ├── @angular/language-service@13.2.7
    ├── @angular/platform-browser-dynamic@13.2.7
    ├── @angular/platform-browser@13.2.7
    ├── @angular/router@13.2.7
    ├── @capacitor/android@3.4.3
    ├── @capacitor/app@1.1.1
    ├── @capacitor/cli@3.4.3
    ├── @capacitor/core@3.4.3
    ├── @capacitor/haptics@1.1.4
    ├── @capacitor/ios@3.4.3
    ├── @capacitor/keyboard@1.2.2
    ├── @capacitor/status-bar@1.0.8
    ├── @ionic/angular-toolkit@6.1.0
    ├── @ionic/angular@6.1.2
    ├── @types/jasmine@3.6.11
    ├── @types/jasminewd2@2.0.10
    ├── @types/node@12.20.48
    ├── @typescript-eslint/eslint-plugin@5.3.0
    ├── @typescript-eslint/parser@5.3.0
    ├── eslint-plugin-import@2.22.1
    ├── eslint-plugin-jsdoc@30.7.6
    ├── eslint-plugin-prefer-arrow@1.2.2
    ├── eslint@7.32.0
    ├── jasmine-core@3.8.0
    ├── jasmine-spec-reporter@5.0.2
    ├── karma-chrome-launcher@3.1.1
    ├── karma-coverage-istanbul-reporter@3.0.3
    ├── karma-coverage@2.0.3
    ├── karma-jasmine-html-reporter@1.7.0
    ├── karma-jasmine@4.0.2
    ├── karma@6.3.19
    ├── protractor@7.0.0
    ├── rxjs@6.6.7
    ├── ts-node@8.3.0
    ├── tslib@2.3.1
    ├── typescript@4.4.4
    └── zone.js@0.11.5

  • Gestures Issue

To introduce this issue I’ll explain its purpose, I’m trying to handle routing by swipe, therefore, I’m using ion-tabs structure to instead of placing an ion-bar place a custom element in which the gesture will be captured to change within a list of routes.

@ViewChild('slider') private slider: ElementRef;

  public details = '';

  constructor(private gestureCtrl: GestureController) { }

  ngOnInit() {
    const gesture: Gesture = this.gestureCtrl.create({
      el: this.slider.nativeElement,
      gestureName: 'slide-gesture',
      threshold: 20,
      onMove: detail => { this.onMove(detail); },
      onEnd: (ev) => { this.end(ev); },
    }, true);
    gesture.enable();
  }
  private end(ev: GestureDetail) {
      console.log('end', ev);
    }

  private onMove(detail) {
    const type = detail.type;
    const currentX = detail.currentX;
    const deltaX = detail.deltaX;
    const velocityX = detail.velocityX;

    this.details = `
      <div>Type: ${type}</div>
      <div>Current X: ${currentX}</div>
      <div>Delta X: ${deltaX}</div>
      <div>Velocity X: ${velocityX}</div>
    `;
  }
}

By now I’ve tried to replicate Ionic documentation about gestures with no result as the browser says:

ERROR Error: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'nativeElement')
TypeError: Cannot read properties of undefined (reading 'nativeElement')
    at GestureRoutingPage.ngOnInit (gesture-routing.page.ts:19:23)
    at callHook (core.mjs:2542:1)
    at callHooks (core.mjs:2511:1)
    at executeInitAndCheckHooks (core.mjs:2462:1)
    at refreshView (core.mjs:9499:1)
    at renderComponentOrTemplate (core.mjs:9598:1)
    at tickRootContext (core.mjs:10829:1)
    at detectChangesInRootView (core.mjs:10854:1)
    at RootViewRef.detectChanges (core.mjs:21451:1)
    at StackController.setActive (ionic-angular.js:2526:48)
    at resolvePromise (zone.js:1262:1)
    at resolvePromise (zone.js:1216:1)
    at zone.js:1329:1
    at _ZoneDelegate.push.3484._ZoneDelegate.invokeTask (zone.js:443:1)
    at Object.onInvokeTask (core.mjs:25535:1)
    at _ZoneDelegate.push.3484._ZoneDelegate.invokeTask (zone.js:442:1)
    at Zone.push.3484.Zone.runTask (zone.js:214:1)
    at drainMicroTaskQueue (zone.js:632:1)

Github Repo for reproduce: here

A few things here,

Having @ionic/angular installed globally is not recommended as it is a per-project/local dependency. Having it install globally will do nothing besides taking up space on your machine.

The CLI will create a project with the latest stable releases of Ionic and the framework of you pick. It is not recommended to use old release of the framework.

No, it does not. You will need to use ionic/angular version 6

I do not recommend doing this for a few reasons.

  • Browser market share: Chrome is already on version 100, and most devices are kept up to date automatically by updates. The chances of people being stuck on versions of chrome that old are very very rare.

  • Security updates: Browser versions exist for a reason. They not only provide new features (which Ionic depends on), but also address security issues and exploits in older browsers

Gesture issue

For your gesture issue, it’s a matter of targeting an element before it’s been rendered to the DOM. ngOnInit fires right when the component is created, but before the template has been rendered. The solution is to use ngAfterViewInit which fires after the component renders the template

index fafe752..5d27312 100644
--- a/src/app/gesture-routing/gesture-routing.page.ts
+++ b/src/app/gesture-routing/gesture-routing.page.ts
@@ -1,4 +1,4 @@
-import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
+import { Component, ElementRef, OnInit, ViewChild, AfterViewInit } from '@angular/core';
 import { Gesture, GestureController, GestureDetail } from '@ionic/angular';

 @Component({
@@ -6,7 +6,7 @@ import { Gesture, GestureController, GestureDetail } from '@ionic/angular';
   templateUrl: './gesture-routing.page.html',
   styleUrls: ['./gesture-routing.page.scss'],
 })
-export class GestureRoutingPage implements OnInit {
+export class GestureRoutingPage implements AfterViewInit {

   @ViewChild('slider') private slider: ElementRef;

@@ -14,7 +14,7 @@ export class GestureRoutingPage implements OnInit {

   constructor(private gestureCtrl: GestureController) { }

-  ngOnInit() {
+  ngAfterViewInit() {
     const gesture: Gesture = this.gestureCtrl.create({
       el: this.slider.nativeElement,
       gestureName: 'slide-gesture',

I’d suggest looking over Angular’s life cycle hooks to see what each one does and when it fires.

Just to make sure people are able to help and provide answer to your posts, it’s probably a good idea to limit your forum posts to one topic.

Thank you so much for your time and effort! Also for the well explained setup reasoning!