Dear community,
a few days ago my company decided to upgrade a client’s project (Angular based) to the new Ionic 4 Beta version. 
While we refactored pretty many things easily, there seems to be an issue with Ionic elements that are accessed via the “@ViewChild”-Notation:
/* nav.page.html */
<ion-nav [root]="masterPage" #masterNav></ion-nav>
<ion-nav [root]="detailPage" #detailNav main></ion-nav>
/* nav.page.ts */
export class AbSplitPaneComponent implements OnInit
{
@ViewChild('detailNav') detailNav: Nav;
@ViewChild('masterNav') masterNav: Nav;
}
In our current Ionic 3 project, the ion-nav-Element masterNav is fetched inside of the controller and returns an object like this: Nav {_config, _elementRef, _renderer, _componentName, parent}.
On the other hand, with the almost identical code base, using Ionic 4 Beta the @ViewChild result is an object like this: ElementRef {nativeElement}. Thus, only the element reference is returned which has previously been only an object property of the corresponding component, which is missing now.
It seems like either the ion-nav-Element cannot be resolved by Angular 6 (maybe because it’s a Web Component now?) and thus only the native element can be fetched; or there has been a general refactoring of some kind.
I already tried to add CUSTOM_ELEMENTS_SCHEMA in app.module.ts but this didn’t change anything.
Did anyone of you run into this trouble too, or can reproduce it with some view elements and @ViewChild access? Any help will be very greatly appreciated!
1 Like
I’ve only needed View Child for vanilla JS graphics libraries. The pure Angular/Ionic material I handle more abstractly through providers. I’m tempted to recommend that to you also. It feels as though you’re asking the template to do things that aren’t its job. This was a weakness of Ionic routing – it was page-template driven. Now you can play with things like PathLocationStrategy. You might not need navs at all.
1 Like
Having the exact same issue.
My view
<ion-tabs #tabs [tabbarHidden]="!isAuthenticated" color="primary">
<ion-tab label="Home" icon="home" href="/tabs/(home:home)">
<ion-router-outlet name="home"></ion-router-outlet>
</ion-tab>
<ion-tab label="workspace" icon="home" href="/tabs/(workspace:workspace)">
<ion-router-outlet name="workspace"></ion-router-outlet>
</ion-tab>
<ion-tab label="login" icon="home" href="/tabs/(login:login)">
<ion-router-outlet name="login"></ion-router-outlet>
</ion-tab>
</ion-tabs>
My tabs viewmodel.
export class TabsPage implements OnInit, OnDestroy, AfterViewInit {
@ViewChild('tabs') private tabs: Tabs;
private isAuthenticated: boolean;
private subscription: Subscription;
constructor(
private navController: NavController,
private authService: AuthenticationService
) { }
public async ngOnInit(): Promise<void> {
this.isAuthenticated = await this.authService.isAuthenticated();
console.log(this.tabs);
this.subscription = this.tabs.ionChange.subscribe(async (x) => {
this.isAuthenticated = await this.authService.isAuthenticated();
});
}
public async ngAfterViewInit(): Promise<void> {
console.log(this.tabs);
}
public async ngOnDestroy(): Promise<void> {
this.subscription.unsubscribe();
}
}
The only thing I am getting from the console.log(this.tabs)
is this:
and of course the error
Error: Uncaught (in promise): TypeError: Cannot read property 'subscribe' of undefined
TypeError: Cannot read property 'subscribe' of undefined
Would love to have a solution for this.
To get slides in v4 with ViewChild the code has to be change a bit, maybe it’s the same with Tab
I guess you could try with an ElementRef
or something like Slides ViewChild
The solution provided to me was adding { read: Tabs }
. Like this
@ViewChild('tabs', { read: Tabs }) private tabs: Tabs;
So for the OP it should be
@ViewChild('detailNav', { read: Nav }) detailNav: Nav;
4 Likes
This was the answer I have been looking for… Thanks allot