Home > other >  Passing data through angular router
Passing data through angular router

Time:12-27

I have a school project where i use angular CLI 15 and i need to pass data through the router. I need to pass the variable isAdmin from appComponent to tipsListComponent. appComponent is always displayed and the default route displays tipListComponent inside appComponent.

app.component.ts :

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  public isAdmin = true;
  public isConnected = false;
  title = 'Terraria';
}

app.component.html :

<mat-toolbar>
  <div id="centered">
    <img src="../assets/logo.png" id="logo" routerLink="/" />
  </div>

  <div id="right_nav">
    <button
      [hidden]="isConnected"
      
      mat-flat-button
      color="grey"
      style="background-color: #666b6f; color: white"
      routerLink="/login"
    >
      Se connecter
    </button>
    <button
      [hidden]="isConnected"
      
      mat-flat-button
      color="grey"
      style="margin-left: 4px; background-color: #666b6f; color: white"
      routerLinkActive="activebutton"
      routerLink="/register"
    >
      S'enregistrer
    </button>

    <button
      [hidden]="!isAdmin"
      
      mat-flat-button
      color="grey"
      style="margin-left: 4px; background-color: #666b6f; color: white"
      matTooltip="Outils d'administration"
    >
      <mat-icon>build</mat-icon>
    </button>

    <button
      [hidden]="!isConnected"
      
      mat-flat-button
      color="grey"
      style="margin-left: 4px; background-color: #666b6f; color: white"
      (click)="isConnected = !isConnected"
      matTooltip="Se déconnecter"
    >
      <mat-icon>exit_to_app</mat-icon>
    </button>
  </div>
</mat-toolbar>
<div id="sapcing" style="height: 85px"></div>
<div id="body">
  <router-outlet></router-outlet>
</div>

tip-List.component.ts :

import { Component, Input } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Sort } from '@angular/material/sort';
@Component({
  selector: 'app-tips-list',
  templateUrl: './tips-list.component.html',
  styleUrls: ['./tips-list.component.css'],
})
export class TipsListComponent {
  searchTitle = '';
  searchAuthor = '';
  searchTag = '';
  disableThirdHeader = false;
  tips = [   
    { name: 'Frozen yogurt', tags: '159', author: 'admin' },
    {name: 'Ice cream sandwich',tags: '237',author: 'admin',},
    { name: 'Eclair', tags: '262', author: 'admin' },
    { name: 'Cupcake', tags: '305', author: 'admin' },
    { name: 'Gingerbread', tags: '356', author: 'user' },
  ];

  sortedData = this.tips.slice();

  sortData(sort: Sort) {
    const data = this.tips.slice();

    if (!sort.active || sort.direction === '') {
      this.sortedData = data;
    } else {
      this.sortedData = data.sort((a, b) => {
        const aValue = (a as any)[sort.active];
        const bValue = (b as any)[sort.active];
        return (aValue < bValue ? -1 : 1) * (sort.direction === 'asc' ? 1 : -1);
      });
    }
  }
}

tip-List.component.html :

<mat-form-field >
  <mat-label>Rechercher titre</mat-label>
  <input
    matInput
    placeholder="Ex : Œil de cthulhu"
    [(ngModel)]="searchTitle"
    autocomplete="off"
  />
</mat-form-field>
<mat-form-field >
  <mat-label>Rechercher tag</mat-label>
  <input
    matInput
    placeholder="Ex : Œil de cthulhu"
    [(ngModel)]="searchTag"
    autocomplete="off"
  />
</mat-form-field>

<mat-form-field >
  <mat-label>Rechercher auteur</mat-label>
  <input
    matInput
    placeholder="Ex : Œil de cthulhu"
    [(ngModel)]="searchAuthor"
    autocomplete="off"
  />
</mat-form-field>

<table matSort (matSortChange)="sortData($event)">
  <tr>
    <th mat-sort-header="name">Titre</th>
    <th mat-sort-header="tags">Tags</th>
    <th mat-sort-header="author">Auteur</th>
  </tr>

  <tr
    *ngFor="
      let tip of sortedData
        | filter : searchTitle
        | filterTags : searchTag
        | filterAuthor : searchAuthor
    "
  >
    <td>{{ tip.name }}</td>
    <td>{{ tip.tags }}</td>
    <td>{{ tip.author }}</td>
    <button mat-icon-button>
      <mat-icon color="warn" *ngIf="isAdmin">delete</mat-icon>
    </button>
  </tr>
</table>

i want the last button to appear only if isAdmin from appComponent is true

I've tried importing isAdmin to the component and using route parameters

CodePudding user response:

Since probably more than one component needs to have access to the value of isAdmin, you should assign this value to a variable in a service, and inject the service in every component you need the value.

Since the value of isAdmin could change - e.g. after logging in - and would probably come from an HTTP request, you should use an Observable to hold the value.

It could look like this:

session.service.ts:

import { Observable, of } from 'rxjs';

@Injectable({
    providedIn: 'root'
})
export class SessionService {

    public isAdmin: Observable<boolean> = of(true)

}

any component that needs the value of isAdmin:

import { Observable } from 'rxjs';

@Component()
export class TipListComponent {

    public isAdmin: Observable<boolean> = this.sessionService.isAdmin

    constructor(
        private readonly sessionService: SessionService
    ) {
    }

}

in the component template:

<div *ngIf="isAdmin | async">This user is an admin!</div>

CodePudding user response:

What you are looking for is called @Input and @Output. Each component can have an @Input which is essentially a custom property you can set via the html such as:

--- my-custom-component.ts

@Component()
export class MyCustomComponent {
   @Input()
   isAdmin: boolean = false; // default value, in case it was not configured in the html.
}


--- appComponent.html

<my-custom-component [isAdmin]="myVariable"></my-custom-component>

You can find the full explanation in the Angular Documentation along with a full step-by-step example.

  • Related