I have problem with mat-drawer in Angular Material. I want to save my state to localstorage but mat-drawer is always opened.
Sidenav have expanded part and closed expanded part when stay mat-icons without text. When you click on bottom button Hide, the sidenav is Close but after refresh page Sidenav is again expanded (but in the localstorage is close).
Looks like this:
Sidenav is open but in local storage is closed
Do you know how resolve this thing? Thank you!
Source code:
app.component.html
<mat-drawer-container class="content-container" autosize >
<mat-drawer
mode="side"
class="sidenav"
disableClose="true"
opened="true">
<div class="sidenav-container">
<mat-nav-list>
<a class="nav-item nav-link" mat-list-item routerLink="/private/dashboard" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
<mat-icon style="padding-right:5px;" matTooltipPosition="right" [matTooltipDisabled]="disabledTooltip">dashboard</mat-icon>
<span *ngIf="isExpanded">Dashboard</span>
</a>
<a class="nav-item nav-link" mat-list-item routerLink="/private/companies" routerLinkActive="active">
<mat-icon style="padding-right:5px;">stars</mat-icon>
<span *ngIf="isExpanded">Subjects</span>
</a>
<a class="nav-item nav-link" mat-list-item routerLink="/private/users" routerLinkActive="active">
<mat-icon style="padding-right:5px;">group</mat-icon>
<span *ngIf="isExpanded">Users</span>
</a>
<a class="nav-item nav-link" mat-list-item routerLink="/private/api-customers" routerLinkActive="active">
<mat-icon style="padding-right:5px;">beenhere</mat-icon>
<span *ngIf="isExpanded">Clients</span>
</a>
<a class="nav-item nav-link" mat-list-item routerLink="/private/applications" routerLinkActive="active">
<mat-icon style="padding-right:5px;">apps</mat-icon>
<span *ngIf="isExpanded">Apps</span>
</a>
<a class="nav-item nav-link" mat-list-item routerLink="/private/calendar" routerLinkActive="active">
<mat-icon style="padding-right:5px;">calendar_today</mat-icon>
<span *ngIf="isExpanded">Calendar</span>
</a>
</mat-nav-list>
<div class="sidenav-bottom">
<mat-nav-list>
<a class="nav-item nav-link" mat-list-item (click)="onSidenavToggle()">
<mat-icon *ngIf="isExpanded">arrow_back_ios</mat-icon>
<mat-icon *ngIf="!isExpanded">arrow_forward_ios</mat-icon>
<span *ngIf="isExpanded">Hide</span>
</a>
</mat-nav-list>
</div>
</mat-drawer>
<mat-drawer-content>
Page content
</mat-drawer-content>
</mat-drawer-container>
app.component.ts
import {Component, HostListener, Inject, OnInit} from '@angular/core';
import { Router } from '@angular/router';
import {Subject} from 'rxjs';
@Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
isExpanded = true;
constructor(
private sidenavService: SidebarService) {
this.sidenavService.setHideSidebar(this.sidenavService.isHideSidebar());
}
onSidenavToggle() {
this.isExpanded = !this.isExpanded;
this.sidenavService.setHideSidebar(!this.sidenavService.isHideSidebar());
this.sidenavService.sideBarState$.next(this.isExpanded);
}}
sidebar.service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable()
export class SidebarService {
public sideBarState$: Subject<boolean> = new Subject<boolean>();
constructor() {
const initialValue = localStorage.getItem('isExpanded');
this.sideBarState$.next(initialValue === 'close');
}
getHideSidebar(): Subject<boolean> {
return this.sideBarState$;
}
setHideSidebar(newValue: boolean): void {
localStorage.setItem('isExpanded', newValue ? 'close' : 'open');
this.sideBarState$.next(newValue);
}
isHideSidebar(): boolean {
return localStorage.getItem('isExpanded') === 'close';
}
}
Turns out the problem is with your isExpanded
in the component. The value is being hard coded to true
and has nothing to do with the service (or the value stored in LOCALSTORAGE).
Some other suggestions are to use the Subject
value alone as the one true source of what isExpanded
should be (Use the EMIT value, do not set it up yourself). Also it would make more sense if you store isExpanded
as true or false, instead of open
or close
. The variable name suggests the value to be a true or false.
import {Component, HostListener, Inject, OnInit} from '@angular/core';
import { Router } from '@angular/router';
import {Subject} from 'rxjs';
@Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
isExpanded;
constructor(
private sidenavService: SidebarService) {
isExpanded = !this.sidenavService.isHideSidebar();
}
onSidenavToggle() {
this.isExpanded = !this.isExpanded;
this.sidenavService.setHideSidebar(!this.sidenavService.isHideSidebar());
this.sidenavService.sideBarState$.next(this.isExpanded);
}}