An issue with Typescript expressions failing to evaluate has been identified in the Angular 8 Router when running

I have encountered an issue while attempting to execute a TypeScript expression within the router module of my Angular application. The expression I am trying to evaluate is as follows:

const check: any = window.innerWidth > 600 ? RouteOneComponent : RouteTwoComponent;

Despite the condition, it consistently routes to the RouteOneComponent, even when the value of window.innerWidth is below 600.

To replicate this behavior, I created a simple application and below is the code from my router module:

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 { }

While it functions correctly on my local machine, building the application with ng build --prod=true causes the expression to default to true and always load the RouteOneComponent, even on mobile devices when accessing localhost:4200/check.

Is there a TypeScript configuration (ts-config.json) that may be causing this behavior? What steps should I take to debug and resolve this issue, considering it only occurs post-build and not locally?

Answer №1

If you're looking for a simple solution, one approach is to redirect to a common component first and then use ng-if in the attached component template to display the appropriate view based on conditions.

Here's an example:

@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;
}

Another option is to utilize dynamic component loading. In this scenario, you would need to make use of ViewContainerRef to access a container reference and load components dynamically using the createComponent method.

Take a look at the following example:

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))    
}}

To explore more about dynamic component loading, refer to the official documentation here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Module Z encountered an unforeseen issue with the import of value X while utilizing the --aot flag

My application experiences significant slowness while loading in the browser (not to mention on mobile, taking 10-15 seconds). Even after running ng build --prod, the performance remains an issue. Attempting to address this with Angular CLI beta 16, I tri ...

The use of findDOMNode has been marked as outdated in StrictMode. Specifically, findDOMNode was utilized with an instance of Transition (generated by MUI Backdrop) that is contained

I encountered the following alert: Alert: detectDOMNode is now outdated in StrictMode. detectDOMNode was given an instance of Transition which resides within StrictMode. Instead, attach a ref directly to the element you wish to reference. Get more inform ...

Split panel vertically with a draggable divider allowing you to customize the height of each section

Recently diving into Angular, I'm working on a vertically split panel with a "drag handle" that allows users to adjust the height of the top and bottom tree panels. While I've managed to implement a three-stage toggle, I'm struggling to get ...

Tips for sending a variable to control a particular panel within an accordion in Angular 2

I have a collection of ngbpanels that are dynamically created using ngFor. I need to expand or collapse a specific panel based on certain conditions, but the ID I provide for the panel is stored in a variable. The code does not recognize the panel ID when ...

Maintaining a fixed header that remains visible while scrolling through a dropdown menu in Angular

In my application, I have a mat-select widget that displays a list of options. When scrolling within the list, I find it difficult to keep track of all the options. I am looking to enhance the user experience by adding a fixed header at the top of the opt ...

Implementing Google Authentication with Angular 6

I recently completed a project in angular 6 that showcases google authentication using the angular-6-social-login plugin. To install it, you can use the following command: npm install --save angular-6-social-login After installing the plugin, I made some ...

Learn how to connect a value to a dropdown in Angular when updating existing data

I am currently working on a dropdown feature that populates with an array of options. Additionally, I have local data that loads in a dialog box when a user selects a row in a table for editing purposes. My goal is to have the selected value from the drop ...

Tips for linking a composite element while utilizing React's forward ref (attribute is not present on forwardRefExoticComponent)

In my Panel component, I have implemented the option for users to utilize compound components. The default header of the panel includes a close button, but I designed it this way to give users the flexibility to create their own custom headers with differe ...

What is the best approach to eliminate the 'false' type within a setState function in React?

Hey, I've been working on a project that involves using the useState hook and dealing with state using generics. I encountered an issue where I manipulated a fetched array within a setState function using the filter method, which resulted in returnin ...

Having trouble establishing a default value for Material Multiselect in Angular 6

I am currently attempting to incorporate a multiselect feature in an Angular application using Material design. However, I am encountering an issue where the default selected types are not working as expected when the page is opened in Edit mode. Displaye ...

Passing data from a child component to a parent component in Angular 6 using MatDialog and EventEmitter

Currently able to establish communication between two components but unsure of how to pass the user-selected value as an Object via event emitter from the MatDialog component to the parent component. I aim to transmit the selected option's value and t ...

Typescript declaration specifies the return type of function properties

I am currently working on fixing the Typescript declaration for youtube-dl-exec. This library has a default export that is a function with properties. Essentially, the default export returns a promise, but alternatively, you can use the exec() method which ...

Accordion border in Bootstrap should be applied to all items except the first one

I am currently implementing Bootstrap accordions in an Angular application and I am facing an issue where I want to have a colored border all around each accordion panel. The problem is that by default, Bootstrap removes the top border from all accordions ...

Getting a "module not found" error in Next.js while trying to import a TypeScript

Check out this code snippet: // lib/customFunction.ts export function customFunction() { console.log("customFunction"); } // pages/homepage.tsx import { GetServerSideProps } from "next"; // works import { exampleFunction } from "../lib/exampleFile.js" ...

Will other functions in the file run if only a single function is imported?

The file bmiCalculator.ts contains the following code: import { isNotNumber } from './utils'; export default function calculateBmi(height: number, weight: number) { const bmi = weight / Math.pow(height / 100, 2); if (bmi < 18.5) { re ...

Using the VSCode debugger to place a breakpoint within a Typescript package that has been symlinked using `npm link`

I'm currently troubleshooting a NodeJS application and its associated typescript packages, which have been linked using `npm link`. The directory structure is as follows: /root/package-a # typescript package /root/package-b # another typescript packa ...

Error in Angular Material Snackbar issue

Within my Angular 4 project, I have successfully implemented MatSnackbar to display useful messages to the user. However, there is one instance where a particular snackbar displays an error. The issue arises when a user attempts to access the application ...

[Simple TypeScript]: Assign the parameter value as the key of the object returned by the function

How do I modify the key of a function returned object to match its parameter's value? Here is my current code: const createCache = <A, T extends string>(name: T, base = {}) => { const cache = base; return { [name]: cache, } as { ...

Problem with connecting Angular data

<body ng-app="myAPP"> <div ng-controller="employeeCtrl"> <table style="border:1px solid gray"> <tr> <th>Employee Name</th> <th>Employee Address</th> <th> ...

Incorporating a Script into Your NextJS Project using Typescript

I've been trying to insert a script from GameChanger () and they provided me with this code: <!-- Place this div wherever you want the widget to be displayed --> <div id="gc-scoreboard-widget-umpl"></div> <!-- Insert th ...