ionic-framework icon indicating copy to clipboard operation
ionic-framework copied to clipboard

bug: certain tab methods missing on framework integrations

Open znotdead opened this issue 4 years ago • 16 comments

Bug Report

Ionic version:

[x] 4.11.5

Current behavior: this.tabs.getTab is not a function

Expected behavior: getTab should return tab component

Steps to reproduce: on page with tabs: @ViewChild(IonTabs, { static: false }) tabs: IonTabs; And run this code:

const currentTab = this.tabs.getSelected();
console.log(this.tabs.getTab(currentTab));

This gives error: ERROR TypeError: "this.tabs.getTab is not a function" In console: error TS2339: Property 'getTab' does not exist on type 'IonTabs'.

According to docs: https://ionicframework.com/docs/api/tabs :

getTab
--
Get a specific tab by the value of its tab property or an element reference.
getTab(tab: string \| HTMLIonTabElement) => Promise<HTMLIonTabElement \| undefined>

Related code:

const currentTab = this.tabs.getSelected();
console.log(this.tabs.getTab(currentTab));

Other information:

Ionic info:

Ionic:

   Ionic CLI                     : 5.4.2
   Ionic Framework               : @ionic/angular 4.11.5
   @angular-devkit/build-angular : 0.803.8
   @angular-devkit/schematics    : 8.3.8
   @angular/cli                  : 8.3.19
   @ionic/angular-toolkit        : 2.0.0

Cordova:

   Cordova CLI       : 9.0.0 ([email protected])
   Cordova Platforms : ios 5.0.1
   Cordova Plugins   : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 4.1.0, (and 8 other plugins)

Utility:

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

System:

   Android SDK Tools : 26.1.1 
   NodeJS            : v12.13.0 
   npm               : 6.12.0
   OS                : Linux 4.15

znotdead avatar Nov 15 '19 04:11 znotdead

Thanks for the issue. What are you hoping to be able to do with getTab? We weren’t clear of the benefit of it in Angular apps, so we didn’t expose it there. We’re willing to add it but would like to understand the use case first.

liamdebeasi avatar Nov 19 '19 21:11 liamdebeasi

I have a page with tabs. Situation: Page1 has opened Tab1. When navigate away from Page1 there are lifecycle events fired up. I do have Page1 ionViewWillLeave but do not have Tab1 ionViewWillLeave. so I tried to do on Page1 ionViewWillLeave event:

  • getSelected tab
  • if it's tab that I'm interested in than getTab to get component
  • call methods for this tab that should be fired on Tab1 ionViewWillLeave.

Of course I do not need getTab if during navigation to another page the next will be called:

  1. Tab1 ionViewWillLeave
  2. Page1 ionViewWillLeave as I'm leaving 2 pages ( Page1 and Tab1) in the same time.

znotdead avatar Nov 20 '19 17:11 znotdead

Apologies for the delay. Thanks for the follow up. Would you be able to provide a repo with you use case that we could debug?

liamdebeasi avatar Dec 10 '19 14:12 liamdebeasi

Yes sure https://github.com/TimberTracks/ionic_tabs_example. To try it out. When you have a menu. You may open some tabs but it will not fire ionWillLeave if you go to another page from menu.

About will Leave. about.page.ts:17:12
Tabs will Enter. tabs.page.ts:13:12
Tab1 will Leave. tab1.page.ts:17:12
Tab2 will Enter. tab2.page.ts:14:12
Tabs will Leave. tabs.page.ts:17:12
About will Enter. about.page.ts:13:12

Tab2 will Enter. tab2.page.ts:14:12 HERE SHOULD BE Tab2 will Leave Tabs will Leave. tabs.page.ts:17:12 About will Enter. about.page.ts:13:12

znotdead avatar Dec 11 '19 05:12 znotdead

My use case for the getTab function is to try and attach data to a tab element, then read that data within the ionTabsWillChange event.

It would be super useful to have the online documentation state which frameworks functions and attributes are present/used in, I waste a lot of time trying to do things that turn out to be impossible due to methods and attributes being specific to certain frameworks but no indicators within the documentation.

sjregan avatar Jan 24 '20 05:01 sjregan

In my case, I need to access a tab to change its label when the user changes a value in a page form. I find it extremely frustrating that the documentation indicates a feature exists that doesn't. It looks like you guys have been aware of this issue for some time. Is it possible to get this method exposed or let people know you're not going to do it and close this thread.

cmeuser avatar Jul 02 '20 21:07 cmeuser

@liamdebeasi is there any way to get an instance of IonTab? i couldn't find a way. If i read the code directly ionic-angular doesn't even use the ion-tab element. However it has a dedicated page in the documentation.

My use case is resetting tabs to their root/inital components/pages on logout.

chriswep avatar Sep 16 '20 14:09 chriswep

@liamdebeasi is there any way to get an instance of IonTab? i couldn't find a way. If i read the code directly ionic-angular doesn't even use the ion-tab element. However it has a dedicated page in the documentation.

My use case is resetting tabs to their root/inital components/pages on logout.

I think that's one of the main reasons why there is some confusion about this. It looks like the default angular tab app created with ionic cli is using a different approach for rendering tabs and their content. In this example the tabs are independent angular components, which do not use the ionic-tab element. So one basic use case for getTab would be to get the currently visible instance if a tab has been changed, since the ionic-events are only accessible from tabs.page.ts and the angular events (e.g. OnInit) are only fired once on app startup. Or is there any other hidden magic which allows to respond on tab changes from within the new selected tab? Using the angular router or a custom service exposing the values from the parent tab.page.ts does not seem like a convenient solution to me.

cmasdf avatar Sep 28 '20 12:09 cmasdf

Dear all,

I can confirm that the issue still exists also for v5.5.4 with VueJS.

I can get the value with property "selectedTab" (not documented) but method "getSelected()" fail with error "is not a function". Same for "select()".

Do you have any plan to resolve this? Seems that VUEJS integration is too buggy for production.

michaelsogos avatar Feb 25 '21 17:02 michaelsogos

Another case: I wanted to try to bypass issue that ionViewWillEnter not fires on Tabs second time after navigations (bug is closed for some reason without fix) and to fire on host page manually ionViewWillEnter functionality again but ... So trying to bypass one ionic bug and another, but there is 3rd bug that do not let to make another hack. Developing on Ionic looks like walking on mine field. =( Bugs exists for years and not fixed. So frustrating and makes code looks like hack on top of another hack. Comments in code also in most part consists of links to ionic bugs and explanations of all bypasses.

znotdead avatar Aug 04 '21 18:08 znotdead

Our use case for having getTab and select methods exposed (in the Angular app) is that we want to speedup the tabs navigation of our app (optimize UX) by listening on onMouseDown/onTouchStart and starting the tab navigation sooner (sooner than onClick).

This is because we are not satisfied with the performance of tab navigation (RUM tells us it takes ~500ms) and doing this trick cuts at least some milliseconds (like ~30-50ms) "for free" (without known side effects).

kirillgroshkov avatar Sep 20 '21 17:09 kirillgroshkov

Probably will help somebody (there are different types of bugs related to angular routing and page having ion-tabs pages as children) Looks like following combination works without different side effects:

  1. Parent tab unsubscribes all child subscriptions on leave.
  2. RouteStrategy (routeReuse === false). so on leave all pages will be destroyed.
  3. when opening -> choose tab directly to needed tab. I have a complex setup with shared service and different events firing by tabs for parent

znotdead avatar Nov 25 '21 20:11 znotdead

Issue still present in Ionic Vue 6.

patriksh avatar Jan 31 '22 21:01 patriksh

This issue continues to exist in Ionic v6.18.2 with Angular :

import { IonTabs } from '@ionic/angular';
// ...
this.tabs.getTab(this.tabs.getSelected());
// Property 'getTab' does not exist on type 'IonTabs'.

ion-tabs.d.ts :

export declare class IonTabs {
    private navCtrl;
    outlet: IonRouterOutlet;
    tabBar: IonTabBar | undefined;
    ionTabsWillChange: EventEmitter<{
        tab: string;
    }>;
    ionTabsDidChange: EventEmitter<{
        tab: string;
    }>;
    constructor(navCtrl: NavController);
    onPageSelected(detail: StackEvent): void;
    select(tabOrEvent: string | CustomEvent): Promise<boolean> | undefined;
    getSelected(): string | undefined;
    static ɵfac: i0.ɵɵFactoryDeclaration<IonTabs, never>;
    static ɵcmp: i0.ɵɵComponentDeclaration<IonTabs, "ion-tabs", never, {}, { "ionTabsWillChange": "ionTabsWillChange"; "ionTabsDidChange": "ionTabsDidChange"; }, ["tabBar"], ["[slot=top]", "*"]>;
}

There's no IonTab.getTab() while it's in the documentation. I need it to change a tab's icon.

NoxFly avatar Mar 14 '22 15:03 NoxFly

the problem "Property 'getTab' does not exist on type 'IonTabs'." is not solved yet?

incal avatar Jun 14 '22 16:06 incal

I just tried with

"@ionic/vue": "^6.0.
"@ionic/vue-router": "^6.0.0",

And getSelected is still missing. I was able to get the selected tab with selectedTab from the ion-tab-bar.

matheuscas avatar Jul 07 '22 13:07 matheuscas

@liamdebeasi may i politely bring this back to your attention? While adding features to our Ionic app i bumped into the hacks i implemented to workaround this issue. Our case is still simply to reset the navigation stack for tabs on certain events (since previously navigated routes become invalid). Short of reloading the whole app there is no straightforward way to do this (that i know of). Regardless of our use case - the documentation of Ionic 7 still lists getting tabs instances as a documented feature (even so the missing implementation was reported 3 1/2 years ago).

I was able to hack a reset feature by writing to an undocumented property directly:

tabs.outlet.stackCtrl.views = []

This causes Ionic to (re-)load the default route for each tab when clicking on a tab-button. From what i see this isn't causing any runtime errors, however obviously this may fail randomly.

Any suggestion on how to better implement this?

chriswep avatar Apr 21 '23 10:04 chriswep