Accessing Route Data in Angular's AppComponent

In my app-routing.module.ts file, I have set up the following routes:

const routes: Routes = [
  {
    path: 'abc/:id', component: AbcComponent, data: { category: 'Public' }
  },
  {
    path: 'xyz/:id/tester/:mapId', component: XyzComponent, data: { category: 'Private' }
  },
  { path: '**', redirectTo: '/page-not-found', pathMatch: 'full'}
]

Now, in my app.component.ts file, I am trying to determine the category of each route based on the URL passed:

For example, visiting http://myapp.com/abc/123 should return the category as Public, while going to

http://myapp.com/xyz/123/tester/456
should return the category as Private.

Here is a snippet of my current code:

constructor(
    private activatedRoute: ActivatedRoute,
    private router: Router
)
{
  checkRouteAndGetCategory()
}

checkRouteAndGetCategory()
{
  this.router.events.pipe(
        filter(event => event instanceof NavigationEnd),
        map(() => this.activatedRoute),
        map(route => {
          while (route.firstChild) route = route.firstChild
          return route
        }),
        filter(route => route.outlet === 'primary'),
        mergeMap(route => route.data)
      ).subscribe(data =>
        console.log('data', data)
      )
}

However, this code does not correctly identify the route. For instance, when I navigate from http://myapp.com/abc/123 to

http://myapp.com/xyz/123/tester/456
, it still retrieves the data for the previous page http://myapp.com/abc/123.

Answer №1

In the app component code snippet below, I have defined the constructor and the ngOnInit method:

constructor(private route: ActivatedRoute) {
}

ngOnInit(): void {
  this.router.events.pipe(
    filter(event => event instanceof NavigationEnd),
    map(() => this.rootRoute(this.route)),
    filter((route: ActivatedRoute) => route.outlet === 'primary'),
    mergeMap((route: ActivatedRoute) => route.data)
  ).subscribe((event: {[name: string]: any}) => {
    this.titleService.setRouteTitle(event['title']);
  });
}

private rootRoute(route: ActivatedRoute): ActivatedRoute {
  while (route.firstChild) {
    route = route.firstChild;
  }
  return route;
}

This is how my app routes are structured:

{ path: 'login', component: LoginComponent, data: { title: 'Login' } }

The responsibility of setting the title is handled by my title service.

One distinction between your approach and mine is that you bind to the router in the constructor, whereas I do it within the ngOnInit method. You might want to try moving your logic to ngOnInit as well. It's uncertain whether this change will yield any difference, but it's worth experimenting with.

Answer №2

Perhaps it would be beneficial to relocate this functionality to a dedicated service, such as CategoryService

CategoryService

import { Injectable } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { filter, map, mergeMap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class CategoryService {
  constructor(private router: Router ) { }
  private routerEvents =  this.router.events;
  private navigationEndEvent = this.routerEvents
    .pipe(filter(event => event instanceof NavigationEnd))
  category$ = this.navigationEndEvent
    .pipe(
      mergeMap(() => this.rootRoute(this.router.routerState.root).data),
      map(({category}: any) => category)
    )
  private rootRoute = (route: ActivatedRoute): ActivatedRoute => {
    return route.firstChild ? this.rootRoute(route.firstChild) : route;
  }
}

Component

constructor(private categoryService: CategoryService) {
  }
  category$ = this.categoryService.category$;
  ...
}

HTML

<span>{{ category$ | async }}</span>

Example on Stackblitz

Answer №3

One convenient method to access route information within a component.

initialize(router:Router, currentRoute:ActivatedRoute) {
    router.events
      .filter(event => event instanceof NavigationEnd)
      .forEach(event => {
        this.title = currentRoute.root.firstChild.snapshot.data.section;
    });
} 

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

Learn how to efficiently disable or enable a button in Angular depending on the selected radio button

In order to disable the button when the remarks are marked as failed. Here is an example scenario: Imagine there is an array containing two to four items. First example: ITEM 1 -> FAILED -> Remarks (required) ITEM 2 -> FAILED -> Remarks (r ...

When in production mode, parameter routing and conditions do not function as expected

I have a straightforward routing setup like the following: import { NgModule } from '@angular/core'; import { PreloadAllModules, RouterModule, Routes } from '@angular/router'; const routes: Routes = [ { path: 'scenario', ...

Ways to determine the generic type of a property value from a decorated property within a decorator

While experimenting with some code, I encountered an issue where the generic type of a property value wasn't being resolved correctly when changing from TValue to (t: TValue) => TValue. Instead of being recognized as the expected number, it was now ...

Creating a dynamic row in an HTML table with elements inside

I have an array of numbers in my angular application that I need to display in an HTML table without truncating them and ending with a comma. Each row should display a maximum of 20 values. How can this be achieved? The array looks like this - let arr ...

core.mjs:6484 ALERT There was an issue with reading the 'name' property as it was undefined

I'm encountering an error message in the console.log that I can't seem to resolve... Here is the error message: core.mjs:6484 ERROR TypeError: Cannot read properties of undefined (reading 'name') https://i.stack.imgur.com/tlun6.png H ...

The correct way to update component state when handling an onChange event in React using Typescript

How can I update the state for 'selectedValues' in a React component called CheckboxWindow when the onChange() function is triggered by clicking on a checkbox? export const CheckboxWindow: React.FC<Props> = props => { const [selected ...

As I attempt to log in, the GitHub API is sending back a message stating that authentication

const fetchUser = async () =>{ let usernameValue : any = (document.getElementById('username') as HTMLInputElement).value; let passwordValue : any = (document.getElementById('password') as HTMLInputElement).value; const ...

Issues arise when Typescript's declaration merging feature does not function correctly when utilizing ts-node

I am currently working on a project that involves using the express-session package. My goal is to modify the session object by adding a user key. req.session.user = 123; After reading through the accepted answer in this question, I learned about declarat ...

The Typescript Decorator is triggered two times

I submitted a bug report regarding Typescript because I suspect there is an issue, although I'm seeking additional insights here as well. This is the scenario. When running the following code: class Person { @IsValueIn(['PETER', ' ...

Top method for dynamically loading a specific component by using its selector as a variable

I'm currently in the process of developing a straightforward game using Angular. The game is structured to consist of multiple rounds, each with unique characteristics that are distinguished by the variable roundType. For instance, round types can in ...

Group data by date in a hashmap

In my Spring Boot backend, I am managing apps and games with a Rating Object that saves rating history in a HashMap. // Number of history by day @ElementCollection(fetch = FetchType.EAGER) private Map<String, Integer> ratingHistory = new HashMap<& ...

CDNify load error causing Grunt Serve to fail

I have encountered an issue with a freshly installed Angular project. When I try to run the grunt serve command, I receive the following error: I am currently using Node 12.6.1 with Source Tree and have confirmed that Bower is properly installed. Loading ...

Issue encountered in Cypress while attempting to locate an identifier beginning with a numeric value

My struggle is with finding an element by id using Cypress. The Cypress selector playground provided the following code: get("#\33 -2") Unfortunately, when I execute this code in Cypress, it results in an error: Syntax error, unrecognized expressio ...

How do I configure an Angular project in Nx Workspace to be served as HTTPS?

Currently, I have an nx workspace set up with an Angular project and a NestJS backend. Everything is compiling and functioning properly. Now, the need has arisen to locally host the Angular app using https for development purposes. Typically, I would use t ...

How can I retrieve the ngx-Summernote runtime value?

I am currently integrating ngx-Summernote into my Ionic 5 + Angular project. Is there a way to access the value using ngModel? I attempted: <div [ngxSummernote]="config" [ngxSummernoteView]="content"></div> The issue I&apo ...

Discover the subsite inventory of a SharePoint site using TypeScript

Is there a way to gather all sub-sites from my SharePoint site and organize them into a list? I initially thought of using this.context.pageContext, but could not locate it. Please excuse my seemingly simple question, as I am still learning TypeScript. ...

Getting stuck in an endless loop while making a call to Axios for data fetch with React Suspense

I am currently working on fetching data using Axios and displaying it within a suspense element. I came across a tutorial that demonstrates this process: https://dev.to/darkmavis1980/a-practical-example-of-suspense-in-react-18-3lln However, I am encounter ...

"Utilize Typescript to dynamically check data types during runtime and receive alerts for any potential

INTRODUCTION I am currently working with Angular 6. In Angular, typescript is utilized to allow you to specify the data type of your function's arguments: public fun1(aaa: number) { console.log(aaa); } If I attempt to call fun1 with a parameter ...

Error occurs in Azure Function Linux Nodejs when trying to use @azure/storage-blob as it cannot read the property 'startsWith' of undefined

While testing my Azure Nodejs Linux function locally, I encountered this issue with the code snippet below: import { BlobServiceClient } from "@azure/storage-blob"; const connectionString = process.env[ "AZURE_STORAGE_CONNECTION_STRING&qu ...

Record the variable as star symbols in the VSTS Extension

I am working on a VSTS extension using Typescript and utilizing the vsts-task-lib Currently, I am encountering an issue with the execSync function, which displays the command being executed. However, I need to hide a token obtained from a service by displ ...