REST API consumption – Angular Services and the Singleton Pattern-2

For the inclusion of a new set, we are using the POST method of the service that calls the API with the verb of the same name. We always pass the URL and, in this case, the body of the request will be a new set of exercises.
To update the set, we use the PUT method passing the body, and for the URL, we use the string interpolation to pass the id value that the API demands in your contract. Finally, to delete, we use the DELETE method, and also using interpolation, we pass the id value of the element we want to delete.
Let’s tailor our DiaryComponent component to consume the refactored service. Our challenge here is to deal with the asynchrony of consuming a REST API via an HTTP request.
First, let’s adjust the initialization of the list of exercises:

@Component({
templateUrl: ‘./diary.component.html’,
styleUrls: [‘./diary.component.css’],
})
export class DiaryComponent implements OnInit {
private exerciseSetsService = inject(ExerciseSetsService);
exerciseList!: ExerciseSetList;
ngOnInit(): void {
this.exerciseSetsService
.getInitialList()
.subscribe((dataApi) => (this.exerciseList = dataApi.items));
}
}

In the DiaryComponent class, we will implement the OnInit interface and create the onInit method. This method is one of the lifecycle events of Angular components, which means that it will be called at some point by Angular when building and rendering the interface.
The onInit method is called after building the component, but before rendering the component. We need to implement this method because the filling of the list of exercises will occur asynchronously. Implementing this initialization in the onInit method will ensure that the data will be there when Angular starts rendering the screen.
In this method, we are using the service, but as it now returns an Observable, we need to call the subscribe method and, within it, implement the initialization of the list. As we are using the smart and presentation component architecture, we can implement the button methods in the DiaryComponent smart component as follows:

newList() {
this.exerciseSetsService
.refreshList()
.subscribe((dataApi) => (this.exerciseList = dataApi.items));
}
addExercise(newSet: ExerciseSet) {
this.exerciseSetsService
.addNewItem(newSet)
.subscribe((_) => this.newList());
}
deleteItem(id: string) {
this.exerciseSetsService.deleteItem(id).subscribe(() => {
this.exerciseList = this.exerciseList.filter(
(exerciseSet) => exerciseSet.id !== id
);
});
}
newRep(updateSet: ExerciseSet) {
const id = updateSet.id ??
”;
this.exerciseSetsService
.updateItem(id, updateSet)
.subscribe();
}

In the newList method, we refactored this to fetch the list elements through the refreshList method.
In the addExercise, deleteItem, and newRep methods, we refactored the previous logic to use the exerciseSetsService service.
Summary
In this chapter, we learned about Angular services and how to correctly isolate the business rule from our applications in a simple and reusable way, as well as how Angular services use the singleton pattern for memory and performance optimization.
We worked with and studied Angular’s dependency injection mechanism and noticed how important it is to be able to organize and reuse services between components and other services. We also learned how to use the inject function for Angular services as an alternative to dependency injection via Angular’s constructor.
Finally, we worked with one of the main uses of services, communication with the backend, and in this chapter, we began to explore the integration of our frontend applications with the backend.
In the next chapter, we will study the best practices for using forms, the main way that our users enter information into our systems.

Write a Comment

Your email address will not be published. Required fields are marked *