There are several ways to manage state with services and the simplest one is named “property bag”. it means that the service is like a bag of properties with no real logic or state management. this type of service exposes simple properties that the components use to communicate state among themselves.
Sometimes a component needs to communicate with itself. Let’s say we have a component named productList that lists products and we filter the list. if we navigate away from that component, the productList component will be destroyed and its component properties will be lost, when we will return to the productList component, it will reinitialize and display, and it won’t remember what we filtered before.
So we need a way for the component to keep its view state somewhere so it can get that state back each time the component is re displayed. we do that by creating a service, in the service we define a property for each bit of state that the component wants to track.
Let’s demonstrate a scenario in which we have a component with a checkbox, whenever the component is added to the DOM it will get the state of the checkbox from a service, the state can be checked or unchecked. For that we we will create a simple property in the service that will keep the state checked or unchecked, and in the component that have the checkbox we will use a property with getter and setter to get the state of the checkbox and set the state of the checkbox whenever we click the checkbox, means the change event will be fired.
import { Injectable } from "@angular/core";
@Injectable({
providedIn: "root"
})
export class PropertiesService {
constructor() {}
isChecked: boolean;
}
import { Component } from "@angular/core";
import { PropertiesService } from "./properties.service";
@Component({
selector: "demo",
templateUrl: "./demo.component.html",
styles: []
})
export class DemoComponent {
constructor(private propertiesService: PropertiesService) {}
get toggelCheckbox(): boolean {
return this.propertiesService.isChecked;
}
set toggelCheckbox(value: boolean) {
this.propertiesService.isChecked = value;
}
onCheckboxChange(data) {
this.toggelCheckbox = !this.toggelCheckbox;
}
}
<label class="container">
<input type="checkbox" [checked]="toggelCheckbox" (change)="onCheckboxChange($event)"/>
demo checkbox
</label>
For components that need to communicate with themselves this technique is great for:
- Retaining view state
- Retaining user selections
keep in mind however that:
- Any component can read the values
- Any component can change the values
For components that need communicate with other components this technique is great for:
- Sharing data or other state
- Communicating state changes
keep in mid however that:
- Any component can read the values
- Any component can change the values
- Components are only notified of state changes if they use template binding