Services
Utilisés pour :
- Fonctionnalités indépendantes d'un composant
- Fournir des données ou des fonctionnalités à plusieurs composants
- Séparer des interactions externes (ex. requêtes à une BD)
Les services sont injectés dans les composants et sont enregistrés (registered) auprès de l'application ou d'un composant.
@Component({
selector: 'app-composant',
templateUrl: './composant.component.html',
styleUrls: ['./composant.component.css'],
providers: [LocalService] // dispo ici et dans les composants enfants seulement
})
export class ComposantComponent {
private globalService = inject(GlobalService)
private localService = inject(LocalService)
}
Appels HTTP dans un service
On utilisera des appels HTTP dans nos services pour charger des données provenent d'une API. Pour cela il faudra tout d'abord configurer l'application pour utiliser le clien HTTP d'Angular.
- Localiser le fichier
app.config.ts - Dans la section
providers, ajouterprovideHttpClient()à ceux déjà présent
- On pourra alors injecter
HttpClientdirectement dans les services de l'application. - On crée ensuite des méthodes utilisant le client pour faire les appels. Cette méthode retourne un
Observable<T>
Exemple
import { HttpClient } from '@angular/common/http';
import {inject, Injectable} from '@angular/core';
import {Film} from '../models/film';
import {Observable} from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class FilmService {
// Injecter le service
private http: HttpClient = inject(HttpClient);
// Méthode qui fait l'appel HTTP et retourne un observable
getAllFilms(): Observable<Film[]> {
return this.http.get<Film[]>(url);
}
}
Utilisation dans un composant
- Injecter le service dans le constructeur du composant
- Appeler la méthode du service (souvent lors de la création du composant)
- S'abonner à la réponse
- Lors de la destruction du composant, se désabonner
import {Component, inject} from '@angular/core';
import { FilmService } from '../../services/film-service';
import {Film} from '../../models/film';
import {map, Subscription, tap} from 'rxjs';
import {CarteFilm} from '../carte-film/carte-film';
@Component({
selector: 'app-liste-films',
imports: [
CarteFilm
],
templateUrl: './liste-films.html',
styleUrl: './liste-films.css'
})
export class ListeFilms {
private filmService: FilmService = inject(FilmService);
films: Film[] = [];
// Créer un objet Subscription nous permet de se désabonner plus tard.
private _filmAbonnement!: Subscription;
ngOnInit() {
this._filmAbonnement = this.filmService.getAllFilms()
.subscribe({
next: films => this.films = films,
error: error => console.log(error),
})
}
ngOnDestroy() {
this._filmAbonnement.unsubscribe();
}
}
Attention
L'utilisation de ! permet d'indiquer au compilateur de TypeScript que la propriété sera initialisée, même s'il ne le voit pas. À utiliser avec prudence.
Observables
- Une collection d'items qui évolue au fil du temps
- Nous devons s'abonner à un observable (subscribe) qui envoie des notifications :
- next : quand le prochain item est émis
- error : une erreur s'est produite; les items ne seront plus émis
- complete: émission terminée
- La méthode pipe est utilisée pour transformer les données au fur et à mesure qu'elles arrivent
- Quand on a terminé on se désabonne (unsubscribe) de l'observable (important !)
- Par convention on ajouter un $ à la fin de la propriété pour désigner les observables
Manipuler les données reçues
- On utilisera
pipeavantsubscribe tap: permet de consulter les données sans les modifiermap: permet la transformation des items reçus
this._filmAbonnement = this.filmService.getAllFilms()
.pipe(
tap(data => console.log(data)),
map(data => data.filter(f => f.anneeParution > 2000)),
)
.subscribe({
next: films => this.films = films,
error: error => console.log(error),
})
Gestion des URL d'une API
Pour gérer facilement l'URL de l'API, on peut utiliser les fichiers d'environnement. Cela permet également de gérer facilement la différence entre les propriétés de développement et de déploiement.
- Générer les fichiers d'environnement à l'aide de
ng generate environments. - Ceci génère les fichiers
environment.tsetenvironment.development.tssitué danssrc/environments. - Configurer chaque fichier pour indiquer si c'est l'environnement de production et l'url de l'API.
-
Notez qu'il est également possible de mettre d'autres propriétés et de les utiliser, par exemple si vous avez une adresse d'api différente pour l'authentification.
-
Pour utiliser dans le code, on importera le fichier
environment.tset on utilisera les variables. - On utilise ce fichier même durant le développement car lors de la génération des fichiers d'environnement, Angular a également créé une configuration de remplacement de fichiers pour utiliser le bon fichier d'environnement selon qu'on déploie la version de développement ou production.
// Extrait du fichier angular.json
"configurations": {
"development": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.development.ts"
}
],
…
Références
Doc Angular sur HttpClient
Pour manipuler les observables
Doc Angular sur les fichiers d'environnement