I am trying to execute a TS expression inside the router module of my angular app. I want to evaluate the following expression, const check: any = window.innerWidth > 600? RouteOneComponent: RouteTwoComponent;
const check: any = window.innerWidth > 600? RouteOneComponent: RouteTwoComponent;
But it always routes to the RouteOneComponent
, even when the window.innerWidth
value is less than 600
I created simple application to reproduce this behavior, and following is my router module code
app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { RouteOneComponent } from "./route-one/route-one.component";
import { RouteTwoComponent } from "./route-two/route-two.component";
const check: any = window.innerWidth > 600 ? RouteOneComponent : RouteTwoComponent;
const routes: Routes = [
{ path: 'web', component: RouteOneComponent },
{ path: 'mob', component: RouteTwoComponent },
//tried this - didn't work after build
{ path: 'check', component: window.innerWidth > 600 ? RouteOneComponent : RouteTwoComponent }
//also tried this - didn't work after build
{ path: 'check', component: check }
//also tried this - didn't work after build
{ path: 'check', component: (() => {return window.innerWidth > 600 ? RouteOneComponent : RouteTwoComponent})() }
//also tried removing the above anonymous function to a named function
//gave error during template compile, function calls not supported in decorators
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
When I compile and run on my local it works mine, when I build ( ng build --prod=true
) and run the application and then go to localhost:4200/check
, the expression fallbacks to being true and always opens the RouteOneComponent
even on mobile.
Is there any TS configuration ( ts-config.json
) that results in such behaviour? What is the approach to debug the issue or fix it, this only happens after build but not in local.
One simple option is you can first redirect to a common component and in that attached compoenent template use ng-if to enable the appropiate compoenent view.
Something like this
@Component({
template: `
<router-one-component *ngIf="isWindowsSizeMorethan600"></router-one-component>
<router-two-component *ngIf="!isWindowsSizeMorethan600"></router-two-component>
`
isWindowsSizeMorethan600: boolean;
ngOnInit() {
this.isWindowsSizeMorethan600 = window.innerWidth > 600;
}
Other option is to use dynamic compoenent loading option. In that case you have to use ViewContainerRef
to get the reference to a container and dynamically load compoenent with createComponent
method.
See the example below
template: `
<ng-template #vc></ng-template>
`
@ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef;
ngAfterViewInit() {
loadComponent(vc);
}
async loadComponent(vcr: ViewContainerRef) {
const { RouteOneComponent } = await import('./somepath/route-one.component');
const { RouteTwoComponent } = await import('./somepath/route-two.component');
vcr.clear();
let component : any = window.innerWidth > 600 ? RouteOneComponent : RouteTwoComponent ;
return vcr.createComponent(
this.cfr.resolveComponentFactory(component))
}}
You can find the complete reference in doc https://angular.io/guide/dynamic-component-loader
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.