Firstly, we have to make the theme-service in our angular app which contains the boolean Subject through which the dark mode is toggled from the components.
What is a Subject?
An RxJS Subject is a special type of Observable that allows values to be multicasted to many Observers.
import { Subject } from 'rxjs';
after that, we have to initiate/declare the boolean Subject as pass it to the theme variable with asObservable() so that it can listen the the activity and toggle the theme
private _themeDark: Subject<boolean> = new Subject<boolean>();
isThemeDark = this._themeDark.asObservable();
your theme-service should be like this,
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ThemeService {
white: string = '#ffffff';
black: string = '#141313';
private _themeDark: Subject<boolean> = new Subject<boolean>();
isThemeDark = this._themeDark.asObservable();
constructor() { }
setDarkTheme(isThemeDark: boolean) {
this._themeDark.next(isThemeDark);
if (isThemeDark == true) {
console.log('Dark Used');
document.documentElement.style.setProperty('--white-color', this.black);
document.documentElement.style.setProperty('--black-color', this.white);
localStorage.setItem('dark', 'true');
}
else {
console.log('Light Used');
document.documentElement.style.setProperty('--white-color', this.white);
document.documentElement.style.setProperty('--black-color', this.black);
localStorage.setItem('dark', 'false');
}
}
}
And we have to use that service in any component to toggle the app theme.
<!-- sample.component.html -->
<div class="text-right">
<div class="custom-control custom-switch">
<mat-checkbox type="checkbox"
class="custom-control-input"
id="darkMode"
[checked]="isThemeDark | async"
(change)="toggleDarkTheme($event)">
<label class="custom-control-label" for="darkMode"></label>
<a class="text-capitalize">Dark Mode</a>
</mat-checkbox>
</div>
</div>
Now, in your components .ts file, import the theme-service you have, and import the observable from rxjs
import { ThemeService } from '../../shared/services/theme/theme.service';
import { Observable } from 'rxjs';
And your components .ts file should be like this, which actually contains the toggle handler that will trigger the subject of theme-service observable.
import { Component, OnInit } from '@angular/core';
import { ThemeService } from '../../shared/services/theme/theme.service';
import { Observable } from 'rxjs';
@Component({
selector: 'app-sample',
templateUrl: './sample.component.html',
styleUrls: ['./sample.component.scss']
})
export class SampleComponent implements OnInit {
isThemeDark: Observable<boolean>;
constructor(
private themeService: ThemeService
) {}
ngOnInit() {
this.isThemeDark = this.themeService.isThemeDark;
}
toggleDarkTheme(checked) {
this.themeService.setDarkTheme(checked.checked);
// console.log("checked >", this.isThemeDark);
console.log("checked >", checked.checked);
}
}
Github Source
https://gist.github.com/muhammadawaisshaikh/9b62e76a3827a7478c59dc30e0eaa8a1
Top comments (2)
Thanks for this tutorial! Worked great!
Really good to know! Thanks for showing us how to go about this Muhammad 😁