I am using ionic4 and Angular 7.2.2, and I created a base component class to be extended by other components and not have to repeat a lot of things that I always use. In order to avoid the constructor injection, and therefore be forced to pass again the params to the base construtor in th extended class, I am using Injector.get.
The problem that experience is that, when used it this way, a lot of Angular or Ionic injectors that work fine if injected in the child constructor, do not work or return empty values when used in the child, using the parent's reference.
I am sure there is something I am missing out, because upon inspection of the injector when using the one from my base class and the one from the child, they are different.
Uppon execution, and going to: http://localhost:8101/home/4
This is the relevant code:
app-routing.module.ts
const routes: Routes = [
{path: '', redirectTo: 'home/4', pathMatch: 'full'},
{path: 'home/:id', loadChildren: './home/home.module#HomePageModule'},
];
home.page.ts
import {Component} from '@angular/core';
import {BasePage} from '../../tests/base.comp.test';
import {ActivatedRoute} from '@angular/router';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage extends BasePage {
constructor(public ar: ActivatedRoute) {
super();
this.activatedRoute.params.subscribe(
(result) => {
console.log(`PARAMS FROM inherited activatedRoute-> `, result); // -> outputs {} WRONG!
}
);
ar.params.subscribe(
(result) => {
console.log(`Params from direct injection-> `, result); // -> outputs {id: "4"} Good!
}
);
}
}
home.module.ts
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {HomePage} from './home.page';
import {BasePageModule} from '../../tests/base.test.module';
@NgModule({
imports: [
BasePageModule,
RouterModule.forChild([
{
path: '',
component: HomePage
}
])
],
declarations: [HomePage]
})
export class HomePageModule {
}
base.test.module.ts
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {IonicModule} from '@ionic/angular';
import {FormsModule} from '@angular/forms';
import {BasePage} from './base.comp.test';
@NgModule({
imports: [
CommonModule,
IonicModule,
FormsModule,
],
declarations: [BasePage],
providers: [],
exports: [
CommonModule,
IonicModule,
FormsModule
]
})
export class BasePageModule {
}
base.comp.test.ts
import {Component, Injector} from '@angular/core';
import {AppInjectorTest} from './app.injector.test';
import {ActivatedRoute, Router} from '@angular/router';
@Component({
selector: 'app-base',
template: '',
})
export class BasePage {
public injector: Injector;
public activatedRoute: ActivatedRoute;
constructor() {
const injector = AppInjectorTest.getInjector();
this.activatedRoute = injector.get(ActivatedRoute);
}
}
app.injector.test.ts
import {Injector} from '@angular/core';
export class AppInjectorTest {
private static injector: Injector;
static setInjector(injector: Injector) {
AppInjectorTest.injector = injector;
}
static getInjector(): Injector {
return AppInjectorTest.injector;
}
}
app.component.ts
import {Component, Injector} from '@angular/core';
import {Platform} from '@ionic/angular';
import {SplashScreen} from '@ionic-native/splash-screen/ngx';
import {StatusBar} from '@ionic-native/status-bar/ngx';
import {AppInjectorTest} from '../tests/app.injector.test';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html'
})
export class AppComponent {
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private injector: Injector
) {
this.initializeApp();
AppInjectorTest.setInjector(injector);
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
}