Issue encountered: Unable to access the property 'loadChildren' as it is undefined, while attempting to configure the path

How can I conditionally load the route path? I've attempted the code below, but it's throwing an error. Can someone guide me on how to accomplish this task?

[ng] ERROR in Cannot read property 'loadChildren' of undefined [ng] i 「wdm」: Failed to compile.

Also:

app-routing.module.ts:21 Uncaught TypeError: Cannot read property 'getLandingPage' of undefined at Module../src/app/app-routing.module.ts (app-routing.module.ts:21) at webpack_require (bootstrap:83) at Module../src/app/app.module.ts (app.component.ts:21) at webpack_require (bootstrap:83) at Module../src/main.ts (main.ts:1) at webpack_require (bootstrap:83) at Object.0 (main.ts:13) at webpack_require (bootstrap:83) at checkDeferredModules (bootstrap:45) at Array.webpackJsonpCallback [as push] (bootstrap:32)

app.routing.module.ts

const routes: Routes = [
  {
    path: "",
    redirectTo: this.getLandingPage(), // here is the issue
    pathMatch: "full",
  },
  {
   path: "tabs",
   loadChildren: "./pages/tabs/tabs.module#TabsPageModule",
  },
  {
   path: 'landing',
  loadChildren: './pages/landing/landing.module#LandingPageModule'
 },
];

export class AppRoutingModule {

  getLandingPage(): string {
    let url = "";
    switch (environment.hotelName) {
      case "h1":
        url = "tabs";
        break;
      case "h2":
        url = "landing";
        break;
      default:
    }
    return url;
  }


}

I have auth.gurad.ts as shown below. I don't think where I can use it for this.

export class AuthGuard implements CanActivate {
  constructor(private router: Router,
    private user: UserService,
    private localStorageService: LocalStorageService) { }
  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
    return new Promise(async resolve => {
      const userInfo: UserInfo = await this.localStorageService.get(LocalStorage.USER_INFO);
      if (userInfo && (moment() < moment(userInfo.expireDate))) {
        this.user.guest = false;
        return resolve(true);
      }
      this.user.guest = true;
      this.router.navigate(["/sign-in"]);
      return resolve(false);
    });
  }
}

Answer №1

A common issue that many people encounter is rogue commas in their code. To fix this issue, make sure to remove the unnecessary comma at the end of your route list. The router interprets this extra comma as a fourth item in the list, which leads to a void 0 or undefined item without the necessary loadChildren property.

const routes: Routes = [
  {
    path: "",
    redirectTo: getLandingPage(),
    pathMatch: "full",
  },
  {
    path: "tabs",
    loadChildren: "./pages/tabs/tabs.module#TabsPageModule",
  },
  {
    path: 'landing',
    loadChildren: './pages/landing/landing.module#LandingPageModule'
  }
];

(be mindful of the missing comma after the 'landing' route entry)

Answer №2

Ensure your router config does not contain programmatic logic

This issue may arise if your router configuration uses anything other than a simple object with string keys and string values.


For instance, I encountered this problem when trying to set a regular expression in the data object of a specific route:

{
  path: 'path', 
  component: MyComponent,
  data: {
    regEx: /^[a-f\d]{24}$/i,
  },
},

The compiler threw an error with a vague message:

ERROR in Cannot read property 'loadChildren' of undefined


I came across similar examples where others faced this issue, like in this GitHub thread where someone used a constant as a key for a resolver:

const SOME_CONSTANT = 'someResolver',

{
  path: 'path',
  component: MyComponent,
  resolve: {
    [SOME_CONSTANT]: SomeResolver, // <-- you can't do this
  },
},

In essence, make sure to avoid defining keys, values, or any other parts of your router configuration programmatically to prevent encountering this issue.

Answer №3

Utilizing Route Guards can simplify your code by implementing a guard in the full match and handling redirects from there. Use conditionals as necessary.

For instance:

const routes: Routes = [
  {
    path: "",
    canActivate: [RouteGuard]
 },
  {
   path: "tabs",
   loadChildren: "./pages/tabs/tabs.module#TabsPageModule",
  },
  {
   path: 'landing',
  loadChildren: './pages/landing/landing.module#LandingPageModule'
 },
];

RouteGuard:

 canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
    return new Promise(async resolve => {
        this.router.navigate([environment.hotelName]);
        resolve(true)
  }
}

Answer №4

It is recommended to define the function getLandingPage() outside of the AppRoutingModule:

const getLandingPage = (): string => {
    let url = "";
    switch (hotelName) {
      case "h1":
        url = "tabs";
        break;
      case "h2":
        url = "landing";
        break;
      default:
    }
    return url;
  };

const routes: Routes = [
  {
    path: "",
    redirectTo: getLandingPage(),
    pathMatch: "full",
  },
  {
    path: "tabs",
    loadChildren: "./pages/tabs/tabs.module#TabsPageModule",
  },
  {
    path: 'landing',
    loadChildren: './pages/landing/landing.module#LandingPageModule'
  },
];

For a Stackblitz example, visit (https://stackblitz.com/edit/angular6-lazy-loading-hroo3l?file=src%2Fapp%2Fapp-routing.module.ts). It uses const hotelName instead of an environment variable due to the absence of environment variables in Stackblitz.

It is also uncertain how well this approach will work with Ahead-Of-Time compilation (AOT).

Answer №5

Encountered the same issue today 'ERROR in Cannot read property 'loadChildren' of undefined'.

It seems like this error can come up in various scenarios. In my case, it turned out to be a simple oversight - I forgot to add an 'export' keyword to a CanActivate class.

Here's how it was:

@Injectable({providedIn: 'root'})
class MyActivator implements CanActivate

What it should have been:

@Injectable({providedIn: 'root'})
export class MyActivator implements CanActivate

Tracking down this error took some time, so I wanted to share it here for others facing the same issue!

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

Obtaining an URL with parameters from a server using Angular 6

I am working on retrieving a URL from the Java backend in my Angular application. I need to specify the folder number in the URL to fetch a list from that specific folder. What format should I use and how can I make it dynamic to accept any folder number, ...

Navigating in Angular 2.0.0-rc1 with routes and setting a default route using use

Is it true that "useAsDefault" has been removed in angular2.0.0-rc1? Any suggestions for a workaround? I noticed in the Angular documentation they are using the OnInit method... Do subroutes still function with the /... notation? Thanks ...

Monitor data changes by utilizing observables in Angular

At the start, I have a boolean variable named loading which is set to false, and there's a button whose text is determined by the value of this variable. To handle this functionality, I created a method as follows: changeBtnTxt() { this.loginBtn = ...

Angular 2 routing malfunctioning

I'm encountering an issue while setting up routing in my application. The error displayed in the console is as follows: angular2-polyfills.js:138 Error: XHR error (404 Not Found) loading http://localhost:9000/angular2/router.js(…) Below is the co ...

The parameter label is being detected as having an any type, as specified in the Binding element 'label'

Currently, I am referencing an example code snippet from react-hook-form. However, upon implementation, I encounter the following error: (parameter) label: any Binding element 'label' implicitly has an 'any' type.ts(7031) The example c ...

Is there a surefire method to ensure that ChromeDriver in Protractor consistently uses the stable version?

Every time Chrome releases an update, I encounter a recurring issue. Allow me to paint the picture: All browsers are at version 83 of Chrome Chrome announces that version 84 is on its way, but it has not been released yet. A new ChromeDriver 84 is rolled ...

AngularJS and TypeScript encountered an error when trying to create a module because of a service issue

I offer a service: module app { export interface IOtherService { doAnotherThing(): string; } export class OtherService implements IOtherService { doAnotherThing() { return "hello."; }; } angular.mo ...

The 'xxx' type is lacking various properties compared to the 'xxx[]' type, such as length, pop, push, concat, and many others

Utilizing typescript and reactjs, the issue lies within this component import type { InputProps } from "../utils/types" const Input = (props: InputProps) => { const makeChildren = () => { return ( <> ...

What is the best way to add a picture using React and Next.js?

Being a novice in React and Next, I recently embarked on a project that involves uploading a profile picture. However, every time I try to upload an image, an error pops up. Error: The src prop (http://localhost:3333/files/ SOME IMAGE.jpg) is invalid on n ...

Steps for implementing a button to erase all created polygons in Leaflet and Geoman

I'm currently utilizing Geoman-free in conjunction with Leaflet to create a map where I can draw polygons. My objective is to develop a custom button within my Angular UI that can clear all the drawn polygons. How can this be achieved? Update: Let m ...

Ways to restrict users from inputting alphabets in TextField using material ui

I've set up a TextField where users can only input positive digits. Currently, I'm using the following onKeyDown event: <TextField label={distanceError} error={!!distanceError} defaultValue={kpoints.distance} on ...

Detecting changes in a readonly input in Angular 4

Here is a code snippet where I have a readonly input field. I am attempting to change the value of this readonly input from a TypeScript file, however, I am encountering difficulty in detecting any changes from any function. See the example below: <inp ...

The Angular component refuses to open

Having some trouble with my navbar containing different components that should open upon selection. The profile component is opening correctly, but the "My favorites" button isn't displaying anything from that component. Here's the code snippet ...

Using Typescript: What is the best way to convert a variable into a specific element of an array?

List of Strings: const myStrings = ["one", "two", "three"]; const newString = "two"; The variable newString is currently just a string, but I would like its type to be an element of myStrings. Is there a way to achi ...

Using regular expressions, replace all instances of " " with ' ' based on certain conditions

I am looking to replace quotes "" with single quotes '' within a string. string = `bike "car" bus "'airplane'" "bike" "'train'"` If a word is inside double quotes, it shoul ...

Troubleshooting Angular 2: Why Array Interpolation is Failing

Greetings everyone, I am diving into Angular 2 and attempting to create a basic Todo application. Unfortunately, I've hit a roadblock. My array interpolation seems to be malfunctioning. Any assistance would be greatly appreciated. Here is my AppCompo ...

Combining a JSON object with a dropdown menu within an Ionic 3 Angular 4 application

I've hit a roadblock while attempting to integrate a JSON response into an ion-option tag in my HTML code: <ion-item> <ion-label>Country</ion-label> <ion-select formControlName="country"> ...

Unable to retrieve JSON data in Angular2 as expected

I am encountering an issue while attempting to retrieve data from a JSON file stored in my assets folder within Angular 2. The data is not displaying as expected despite my efforts. The JSON file I am trying to access is named: test.json [ "{'id ...

Retrieve a list of class names associated with a Playwright element

Can anyone suggest the best method to retrieve an array of all class names for an element in Playwright using TypeScript? I've searched for an API but couldn't find one, so I ended up creating the following solution: export const getClassNames = ...