angulartypescriptangular-router

Typscript error in Angular for a dynamic nav


I'm still learning Angular, and I'm trying to build a dynamic nav. This won't be my main nav, but a duplicate in the footer.

My main nav works fine, an i'm lazy loading in my app.routes.ts.

Here is the error i'm getting:

Application bundle generation failed. [0.250 seconds]

X [ERROR] TS2322: Type '{ path: string; title: string | Type<Resolve<string>> | ResolveFn<string>; }[]' is not assignable to type '{ path: string; title: string; }[]'.
  Type '{ path: string; title: string | Type<Resolve<string>> | ResolveFn<string>; }' is not assignable to type '{ path: string; title: string; }'.
    Types of property 'title' are incompatible.
      Type 'string | Type<Resolve<string>> | ResolveFn<string>' is not assignable to type 'string'.
        Type 'Type<Resolve<string>>' is not assignable to type 'string'. [plugin angular-compiler]

    src/app/components/footer/footer-nav/footer-nav.component.ts:20:4:
      20 │     this.routes = this.router.config.filter(

Here's my component ts

import { Component, inject } from '@angular/core';
import { RouterModule, Router, NavigationEnd } from '@angular/router';

@Component({
  selector: 'footer-nav',
  standalone: true,
  imports: [
    RouterModule
  ],
  templateUrl: './footer-nav.component.html',
  styleUrl: './footer-nav.component.scss'
})
export class FooterNavComponent {
 routes: { 
    path:   string; 
    title:  string;  
  }[] = [];

  constructor(private router: Router) {
    this.routes = this.router.config.filter(
      route => route.path !== '' && route.data && route.title)
      .map(route => ({ path: route.path!, title: route.title!, }
    ));
  }

}

here's my component html

<p>footer-nav works!</p>
<nav>
  @for ( route of routes; track route.title ){
    <li>
      <a [routerLink]="[route.path]" routerLinkActive="active">{{ route.title }}</a>
    </li>
  }

</nav>

and my app.routes.ts

import { Routes } from '@angular/router';


export const routes: Routes = [
  {
    path: '',
    redirectTo: 'en',
    pathMatch: 'full'
  },
  {
    path: 'en',    
    loadComponent: () => import('./pages/home/home.component').then(m => m.HomeComponent),
    title: 'English Home Page ! Web Prototype',
    data:{      
      desciption: 'This is the Web Prototype home page',
    }    
  },
  {
    path: 'en/about-us',    
    loadComponent: () => import('./pages/about-us/about-us.component').then((d) => d.AboutUsComponent),
    title: 'English About Us ! Web Prototype',
    data:{      
      desciption: 'This is he Web Prototype About Us pages',
    }  
  },
  {
    path: 'en/sign-up-reactive',        
    loadComponent: () =>  import('./pages/form/form.component').then((d)  => d.FormComponent),    
    title: 'English Sign Up Form ! Web Prototype',
    data:{      
      desciption: 'This is he Web Prototype About Us pages'
    }  
  },
  {
    path: 'en/sign-up-dynamic',    
    loadComponent: () => import('./pages/sign-up/sign-up.component').then((d) => d.SignUpComponent),
    title: 'English Sign Up Form ! Web Prototype',
    data:{      
      desciption: 'This is he Web Prototype About Us pages'
    }  
  },  
];

Thanks guys!

I"m working off a tutorial I found online, but I feel it was only tag angular 18, and may not work.


Solution

  • title in your route configuration might not always be a string, you need to account for that. Update your FooterNavComponent to handle case

    constructor(private router: Router) {
        // Filter routes that have a valid `path` and `title`, then map to the required type
        this.routes = this.router.config
          .filter(route => route.path && typeof route.title === 'string')
          .map(route => ({ path: route.path!, title: route.title as string }));
      }