After upgrade to beta 7, this.app.getComponent returns undefined


#1

Hi friends,

after I had upgrated to beta7, the method this.app.getComponent is returning undefined, breaking my page.

Here is my code:

tabs.ts

import {Page, IonicApp, NavController} from 'ionic-angular';
import {perdidosPage} from '../perdidos/perdidos';
import {seguindoPage} from '../seguindo/seguindo';
import {meusPetsPage} from '../meuspets/meuspets';
import {NotificationsPage} from '../notifications/notifications';

@Page({
  templateUrl: 'build/pages/tabs/tabs.html'
})
export class TabsPage {
  // this tells the tabs component which Pages
  // should be each tab's root Page
  tabPerdidos: any = perdidosPage;
  tabSeguindo: any = seguindoPage;
  tabMeusPets: any = meusPetsPage;
  notificationPage: any = NotificationsPage;
  nav: any;
  app: any;
  maintabs: any;
  activeTabTitle: string;
  showAdotarBtn: boolean;

  constructor(nav: NavController, app: IonicApp) {
    this.app = app;
    this.nav = nav;
    this.showAdotarBtn = false; // temporario... futuramente vamos implementar algo
    this.maintabs = this.app.getComponent('maintabs');
  }

  goToNotifications() {
    this.nav.push(this.notificationPage);
  }

  getActiveTab() {

    console.log("tabs", this.maintabs);
    this.activeTabTitle = this.maintabs.getSelected().tabTitle;

  }
}

tabs.html:

<ion-navbar *navbar hideBackButton="true">
  <ion-toolbar>
    <ion-buttons start *ngIf="showAdotarBtn">
      <button>
        <ion-icon name="heart"></ion-icon> Adotar
      </button>
    </ion-buttons>

    <ion-buttons end>
      <button (click)="goToNotifications()">
        <ion-icon name="notifications"></ion-icon>
      </button>
      <button>
        <ion-icon name="more"></ion-icon>
      </button>
    </ion-buttons>

    <ion-title>{{activeTabTitle}}</ion-title>
  </ion-toolbar>
</ion-navbar>
<ion-tabs id="maintabs" (change)="getActiveTab()">
  <ion-tab [root]="tabPerdidos" tabTitle="Perdidos" tabIcon="pin"></ion-tab>
  <ion-tab [root]="tabSeguindo" tabTitle="Acompanhando" tabIcon="checkmark"></ion-tab>
  <ion-tab [root]="tabMeusPets" tabTitle="Meus" tabIcon="paw"></ion-tab>
</ion-tabs>

This code worked in beta 6.

If anyone had a clue, please tell me.

Thank you and sorry the bad English.


#2

The getComponent method of IonicApp has been removed. Please use Angular’s ViewChild instead.

https://github.com/driftyco/ionic/blob/2.0/CHANGELOG.md#angular-update-to-200-rc1


#3

I think you’re fighting the framework. Just use the parameter in the change event:

export class TabsPage {
  activeTabTitle: string;

  onTabChanged(tab:Tab) {
    this.activeTabTitle = tab.tabTitle;
  }
}
<ion-tabs (change)="onTabChanged($event)">

#4

Thank you, mate! I did’nt read all the changelog :wink:


#5

Thank you, looks a much more elegant solution.

I’ll try this.


#6

Hello… you did it? because i have the same problem and with the solution in changelog i could not do work. Can you help me?


#7

I do have the same issue here with my code

Before, my TS was

ngAfterViewInit() {
    this._app.getComponent('navBarID').elementRef.nativeElement.setAttribute(this._headerColor, true);
}

I changed my code to reflect beta 7, but don’t know how to get my above code converted with the ViewChild

html

<ion-navbar *navbar #navBarId>
...
</ion-navbar>

ts

export class MyClass {
    @ViewChild(navBarId) _navbar: Navbar;

...

    ngAfterViewInit() {
        this._navbar....
}

this._navbar is undefined and I don’t know what to put next to change the navbar color like suggested here


#8

Why are you doing view things in controller-land? Why can’t you just set attributes in your template?


#9

Hi rapropos, in my case i try use a component and in the last version of ionic2 i use like icarus and all work so… you can help? how you get a component with viewchild because the code on the changelog dont work for me


#10

I can make it work with these modifications:

import {Page, IonicApp, NavController} from 'ionic-angular';
import {ViewChild} from '@angular/core'
import {perdidosPage} from '../perdidos/perdidos';
import {seguindoPage} from '../seguindo/seguindo';
import {meusPetsPage} from '../meuspets/meuspets';
import {NotificationsPage} from '../notifications/notifications';

@Page({
  templateUrl: 'build/pages/tabs/tabs.html'
})

export class TabsPage {
  // this tells the tabs component which Pages
  // should be each tab's root Page
  tabPerdidos: any = perdidosPage;
  tabSeguindo: any = seguindoPage;
  tabMeusPets: any = meusPetsPage;
  notificationPage: any = NotificationsPage;
  nav: any;
  app: any;
  activeTabTitle: string;
  showAdotarBtn: boolean;

  @ViewChild('maintabs') tabs:any;

  constructor(nav: NavController, app: IonicApp) {
    this.app = app;
    this.nav = nav;
    this.showAdotarBtn = false; // temporario... futuramente vamos implementar algo
  }

  goToNotifications() {
    this.nav.push(this.notificationPage);
  }

  getActiveTab() {

    this.activeTabTitle = this.tabs.getSelected().tabTitle;

  }
}

#11

But i cannot use the class like this… i got a error in console. i wiil show my code, and my problems is get the component not a page. The component is in app.html.

App class

`import {App, Platform,Events} from ‘ionic-angular’;
import {ViewChild} from ‘@angular/core’;
import {StatusBar} from ‘ionic-native’;
import {HomePage} from ‘./pages/home/home’;
import {LancamentoPage} from ‘./pages/lancamento/lancamento’;
import {CategoriaPage} from ‘./pages/categoria/categoria’;
import {LoadingModal} from ‘./components/loading/loading’;
@App({
templateUrl: ‘build/app.html’,
directives:[LoadingModal],
config: {
backButtonText: ‘Go Back’,
modalEnter: ‘modal-slide-in’,
modalLeave:‘modal-slide-out’
}, // http://ionicframework.com/docs/v2/api/config/Config/
})

export class MyApp {

static get parameters() {
return [[Platform],[Events]];
}

constructor(platform,events) {

this.home = HomePage;
this.categoria = CategoriaPage;
this.lancamento = LancamentoPage;
this.rootPage = this.home;

platform.ready().then(() => {....`

My Component

`import {Component} from ‘@angular/core’;
import {IONIC_DIRECTIVES} from ‘ionic-angular’;

@Component({
selector:‘loading-modal’,
templateUrl:‘build/pages/components/loading-modal/loading-modal.html’,
directives:[IONIC_DIRECTIVES]
})

export class LoadingModal {
constructor() {
this.ocupado = false;
}

show(){
this.ocupado = true;
}

hide(){
this.ocupado = false;
}

}
`

I call put my component on the app.html

<ion-nav [root]="rootPage" #conteudo></ion-nav> <loading-modal id="loading"></loading-modal>

in the beta 6 i used
this.loading = app.getComponent('loading') //loading is the id of component in app.html

and then i able call the methods in my component class to show ou hide the loading…

this.loading.show() or this.loading.hide()

now i try…

`import {Page,Modal,Alert,Events,NavController} from “ionic-angular”;
import {ViewChild} from “@angular/core”;
import {Toast} from “ionic-native”;
import {ModalLancamentoPage} from “…/modal/modal-lancamento”;
import {ModalConfigPage} from “…/modal/modal-config”;
import {DAOLancamento} from “…/…/dao/dao-lancamento”;
import {LancamentoAdapter} from “…/…/utils/lancamento-adapter”;
import {DataUtil} from “…/…/utils/data-utils”;
import {DataFilter} from “…/…/components/data/data-filter”;
import {NumberUtil} from “…/…/utils/number-utils”;
import {SaldoPage} from “…/saldo/saldo”;
import {DaoConfig} from ‘…/…/dao/dao-config’;
import {LoadingModal} from “…/…/components/loading/loading”;
@Page({
templateUrl:“build/pages/lancamento/lancamento.html”,
directives:[DataFilter],
queries:{
loading: new ViewChild(‘loading’)
}
})

export class LancamentoPage {
static get parameters(){
return [[NavController],[Events]];
}

constructor(nav,events) {
this.loading.show()//exemple…
`

and in app.html i put

<loading-modal #loading></loading-modal>

but i got error

EXCEPTION: Error: Uncaught (in promise): EXCEPTION: Error in :0:0 ORIGINAL EXCEPTION: TypeError: Cannot read property 'show' of undefined

Help me please… :cry:


#12

Again, why are you doing things in your controller that are intended to be done in the view? There are several ways of conditionally showing or hiding content written in the template that are much more straightforward - ngIf and [hidden] for example.


#13

Humm… yeah, now i understand what you say… so i can put the loading in the template and show or hide in the view side… i’ll try this now… thanks @rapropos :slight_smile:


#14

Hi @rapropos,

In my case, I want to change the ion-navbar color depending who is calling.

I have a another page before that one where the user will select an item. Depending of the selection, the next page, that is containing the ion-navbar #navbarid, will have the color of the selected item pass through navParams.

Any suggestion to solve that issue? I don’t want to have 5 or more ngIf or hidden and I don’t think it is the right solution. Do you?

Thanks in advance for you input


#15

This is a relatively complex concept, because navbars have a bunch of other content that has their own ideas about what “the color” means, but in general I would do this with a dynamically set attribute. For really just “the ion-navbar color”, it could be done directly like this:

@Page()
export class MyPage {
  // modifying this variable should change the element style
  navbarColor: string = "#224466";
}
<ion-navbar navbar [style.color]="navbarColor">

That won’t, however, override other CSS color settings for things inside the navbar. If you want to do that, I would define some CSS rules and dynamically set a class with something like this:

@Page()
export class MyPage {
  // assigning to me will change classes on the navbar
  navbarFlavor = "green";
}
<ion-navbar [ngClass]="navbarFlavor" *navbar>
  <button>hello world</button>
</ion-navbar>
ion-navbar.green button {
  background-color: green;
}

ion-navbar.red button {
  background-color: red;
}

#16

I just followed your other suggestion here and it worked in my case