简体   繁体   中英

Typescript expressions not evaluating in Angular 8 Router on production build

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM