Menampilkan Data User Pada maincontent

Pertama, pada sidenav, kita perlu tambahkan routerlink. Buka file sidenav.component.html, lalu ubah link href.

<mat-drawer-container class="app-sidenav-container" autosize>
    <mat-drawer #drawer class="app-sidenav mat-elevation-z10" [mode]="isScreenSmall ? 'over' : 'side' " [opened]="!isScreenSmall">
        <mat-toolbar color="primary">
            <span>Contact</span>
        </mat-toolbar>
        <mat-nav-list>
            <mat-list-item *ngFor="let user of users | async">
                <!-- tambahkan router link pada element a -->
               <a matLine [routerLink]="['/contactmanager', user.id]">
                    <mat-icon svgIcon="{{ user.avatar }}"></mat-icon>   {{ user.name }}
                </a>
            </mat-list-item>
        </mat-nav-list>
    </mat-drawer>
  
    <div class="app-sidenav-content">
        <app-toolbar (toggleSidenav)="drawer.toggle()"></app-toolbar>
        <div class="wrapper">
            <router-outlet></router-outlet>
        </div>
    </div>
  
</mat-drawer-container>

Buka file contactmanager.module.ts, registrasikan route diatas.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FlexLayoutModule } from '@angular/flex-layout';
import { FormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';

import { MaterialModule } from '../shared/material.module';

import { ContactmanagerAppComponent } from './contactmanager-app.component';
import { ToolbarComponent } from './components/toolbar/toolbar.component';
import { MainContentComponent } from './components/main-content/main-content.component';
import { SidenavComponent } from './components/sidenav/sidenav.component';
import { UserService } from './services/user.service';
import { HttpClientModule } from '@angular/common/http';


const routes : Routes = [
  {
    path: '', component: ContactmanagerAppComponent, 
    children: [
      {path: ':id', component: MainContentComponent},
      {path: '', component: MainContentComponent}
    ]
},
  {path: '**', redirectTo: ''}
]

@NgModule({
  declarations: [
    ContactmanagerAppComponent,
    ToolbarComponent,
    MainContentComponent,
    SidenavComponent,
  ],
  imports: [
    CommonModule,
    HttpClientModule,
    FormsModule,
    MaterialModule,
    FlexLayoutModule,
    RouterModule.forChild(routes)   
  ],
  providers:[
    UserService
  ]
})
export class ContactmanagerModule { }

Kemudian buka file main-content.component.ts, kita handle routing diatas.

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import { User } from '../../models/user';
import { UserService } from '../../services/user.service';

@Component({
  selector: 'app-main-content',
  templateUrl: './main-content.component.html',
  styleUrls: ['./main-content.component.scss']
})
export class MainContentComponent implements OnInit {
  user! : User | undefined;

  constructor(private route: ActivatedRoute, private userSrv: UserService) { }

  ngOnInit(): void {
    this.route.params.subscribe(params=>{
      const id  = params['id'];
      this.userSrv.users.subscribe(users=>{
        if(users.length==0) return;
        this.user = this.userSrv.loadUserById(id);
      });
      
    });
  }

}

Kemudian buka file user.service.ts, implementasikan method untuk loadUserById.

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { User } from '../models/user';

@Injectable({
  providedIn: 'root'
})
export class UserService {
  private _users : BehaviorSubject<User[]>;

  private dataStore : {
    users : User[]
  }

  constructor(private http: HttpClient) { 
    this.dataStore = {users :[]};
    this._users = new BehaviorSubject<User[]>([]);
  }

  get users(): Observable<User[]>{
    return this._users.asObservable();
  }

  loadAllUser(){
    const url = 'https://spangularmaterial-default-rtdb.firebaseio.com/users.json';

    return this.http.get<User[]>(url).subscribe(data =>{
      this.dataStore.users = data;
      this._users.next(Object.assign({}, this.dataStore).users);
    }, error => {
      console.log('error load user');
    });
  }

  loadUserById(id:number){
    return this.dataStore.users.find(x=> x.id == id);
  }

}

Kemudian kita buka main-content.component.html, tambahkan code untuk menampilkan data user.

Link dokumentasi component yang digunakan:

<div *ngIf="!user">
    <mat-spinner></mat-spinner>
</div>
<div *ngIf="user">
    <mat-card>
        <mat-card-header>
            <mat-icon mat-card-avatar svgIcon="{{user.avatar}}"></mat-icon>
            <mat-card-title>{{ user.name }}</mat-card-title>
            <mat-card-subtitle>Birthday {{ user.birthDate | date:'d LLLL' }}</mat-card-subtitle>
          </mat-card-header>
          <mat-card-content>
            <p>{{ user.bio }}</p>
          </mat-card-content>        
    </mat-card>
</div>

Kemudian kita buka sidenav.component.ts, lakukan modifikasi untuk menampilkan data user index pertama, jika tersedia datanya.

Kita juga perlu menambahkan code untuk menutup sidenav setelah diclick (pada small screen).

import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';
import { Component, OnInit, ViewChild } from '@angular/core';
import { Observable } from 'rxjs';
import { UserService } from '../../services/user.service';

import { User } from '../../models/user';
import { Router } from '@angular/router';
import { MatDrawer, MatSidenav } from '@angular/material/sidenav';

const SMALL_WIDTH_BP = 720;


@Component({
  selector: 'app-sidenav',
  templateUrl: './sidenav.component.html',
  styleUrls: ['./sidenav.component.scss']
})
export class SidenavComponent implements OnInit {
  public isScreenSmall! : boolean;
  users! : Observable<User[]>;

  //tambahkan viewchild untuk akses sidenav
  @ViewChild(MatDrawer) drawer! : MatDrawer;

  //inject router
  constructor(private breakpointObs : BreakpointObserver, private userSrv : UserService, private router: Router) { }

  ngOnInit(): void {
    this.breakpointObs
    .observe([`(max-width: ${SMALL_WIDTH_BP}px)`])
    .subscribe((state: BreakpointState)=>{
      this.isScreenSmall = state.matches;
    });

    this.users = this.userSrv.users; 
    this.userSrv.loadAllUser();

    this.users.subscribe(data =>{
      //modifikasi untuk menampilkan user idx pertama
      if(data.length>0) this.router.navigate(['/contactmanager', data[0].id]);
    });

    //menutup sidenav setelah user dipilih.
    this.router.events.subscribe(()=>{
      if(this.isScreenSmall){
        this.drawer.close();
      }
    });
  }

}
Sharing is caring:

Leave a Comment