1

I have been working an app with Angular 8.

I am currently trying to set the page title from the router. For this purpose, in app.module.ts I have:

In app.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  constructor() {}
  public title: String = 'Employees';

  changeTitle(val: String) {
    this.title = val;
  }
}

In app.component.html:

<app-navbar></app-navbar>
<div class="container">
  <h1 class="mt-2 mb-3">{{ title }}</h1>
  <router-outlet (onSetTitle)="changeTitle($event)"></router-outlet>
</div>

In employee-details.component.ts:

import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Employee } from '../../models/empModel';
import * as data from '../../data/employees';

@Component({
  selector: 'app-employee-details',
  templateUrl: './employee-details.component.html',
  styleUrls: ['./employee-details.component.css'],
})
export class EmployeeDetailsComponent implements OnInit {
  constructor(private ActivatedRoute: ActivatedRoute) {}

  @Output() onSetTitle = new EventEmitter<String>();
  public empsArray: Employee[] = data.employees;
  public employee: any = {};

  public setTitle() {
    console.log(this.ActivatedRoute.snapshot.data['title']);
    this.onSetTitle.emit(this.ActivatedRoute.snapshot.data['title']);
  }

  public getEmployee() {
    const empno = Number(this.ActivatedRoute.snapshot.paramMap.get('empno'));
    this.employee = this.empsArray.find((item) => item.empno == empno);
  }

  ngOnInit() {
    this.setTitle();
    this.getEmployee();
  }
}

Stackblitz

I have put together a Stackblitz too.

The problem

The initial value of the title variable does not change, after navigating to the EmployeeDetailsComponent even though the setTitle() method does return the correct value for the title variable.

Questions

  1. What am I doing wrong?
  2. What is the most reliable way to fix this issue?
Razvan Zamfir
  • 4,209
  • 6
  • 38
  • 252
  • 2
    My suggestion would be to use a service. Routes keep your components decoupled from the rendering hierarchy, don't try to change that – Navitas28 May 23 '23 at 12:49

4 Answers4

1

I think you can not add a click event to the router outlet. This is not the proper way.

Here is the solution on StackOverflow.

How to change page title with routing in Angular application?

1

My suggestion would be to use a service. Routes keep your components decoupled from the rendering hierarchy, don't try to change that

You can create a custom that allows you to do that or more common, use a shared service to communicate between parent component and routed component. Source

Navitas28
  • 745
  • 4
  • 13
1

You should avoid using eventEmitter through router-outlet.

Create a service (TitleService) to share the data between your AppComponent and EmployeeDetailsComponent through an Observable.

tlvi38
  • 281
  • 1
  • 6
1

You dont need the output part in employee-details.component.ts and in <router-outlet> and you can remove that function at all.

And solution to this was receiving the datas that you gave in component declaration and not in the Output() from employee-details.component.ts

Link to Demo

Link to stackblitz working version

If you find it helpful mark it as answered!

gentbrika
  • 137
  • 6
  • I don't know what you changed. Can you provide relevant code in the answer, so that I can _understand_ what you did? Thanks! – Razvan Zamfir May 24 '23 at 06:11
  • The solution to this was receiving the title from datas that you assigned to routes in app.module.ts. In app.component.ts (line 10-16) is the way that we got the datas and assigned it to the variable title and each time we change the route it changes the titles dynamically. – gentbrika May 24 '23 at 07:31
  • **Do you know how I can [display the contents of every table row directly in the tr tag](https://stackoverflow.com/q/76323307/4512005)?** :) – Razvan Zamfir May 24 '23 at 12:42