REST API consumption – Angular Services and the Singleton Pattern-1
One of the main uses of Angular services is undoubtedly communication with the backend of the application, using the Representational State Transfer (REST) protocol.
Let’s learn about this feature in practice by preparing our project to consume its backend.
First, let’s upload the backend locally by accessing the gym-diary-backend folder and using the following command in your command-line prompt:
npm start
We can leave this command running and can now create the services for the consumption of the API.
To carry out this consumption, Angular has a specialized service – HttpClient. To use it, we will first import its module into the app.module.ts file:
import { NgModule } from ‘@angular/core’;
import { BrowserModule } from ‘@angular/platform-browser’;
import { AppRoutingModule } from ‘./app-routing.module’;
import { HttpClientModule } from ‘@angular/common/http’;
import { AppComponent } from ‘./app.component’;
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AppRoutingModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
Our project’s backend API returns some JSON, containing the list of exercises for the day. As good practice, we should create an interface to facilitate typing and the manipulation of the results in our frontend application. In the exercise-set.ts file, we will add the following interface:
export interface ExerciseSetListAPI {
hasNext: boolean;
items: ExerciseSetList;
}
Now we can refactor our ExerciseSetsService service to use HttpClient:
export class ExerciseSetsService {
private httpClient = inject(HttpClient);
private url = ‘http://localhost:3000/diary’;
getInitialList(): Observable {
return this.httpClient.get(this.url);
}
refreshList(): Observable {
return this.httpClient.get(this.url);
}
}
First, we inject the HttpClient service into our class using the inject function. We then create the url variable to contain the endpoint of this service that will be used in the service’s methods.
Finally, we refactor the getInitialList and refreshList methods to consume the project’s API. Initially, they have the same implementation, but we will improve this code throughout the book.
An important change was made so that the method does not return the list of exercises, but an Observable that contains the list of exercises. This occurs because the operation involving consuming a REST API happens asynchronously, and through the use of RxJS and its Observables, Angular handles this asynchronicity. We will go deeper into this topic in Chapter 9, Exploring Reactivity with RxJS.
Using the HttpClient service to consume a GET-type API, we declare the return type represented here by the ExerciseSetListAPI type and the service’s get method, passing the URL of the endpoint that we are going to consume as a parameter.
Let’s now add the other methods to complete our service:
addNewItem(item: ExerciseSet): Observable {
return this.httpClient.post(this.url, item);
}
updateItem(id: string, item: ExerciseSet): Observable {
return this.httpClient.put(${this.url}/${id}
, item);
deleteItem(id: string): Observable {
return this.httpClient.delete(${this.url}/${id}
);
}
}