Envoyez des requêtes simples

Une application web dynamique aura besoin de communiquer avec un serveur, que ce soit pour récupérer, créer, modifier ou supprimer des données. Avec Angular, ces requêtes sont gérées avec HttpClient.

Installez et lancez l'application Dwelio

Une fois le repo cloné sur votre machine de développement :

  • placez-vous sur la branchechapitre-2/début

  • installez les dépendances avecnpm install

  • démarrez le serveur backend avecnpm run start:server

  • démarrez le serveur de développement Angular avecng serve

Avec votre navigateur, comme d'habitude, vous pouvez naviguer sur http://localhost:4200 et vous devriez y voir l'application Dwelio :

Une grille de biens immobiliers à vendre
L'application Dwelio

Pour l'instant, tout ce que vous y voyez est codé en dur : votre mission pendant le reste de ce cours est de tout rendre dynamique !

Récupérez la liste des biens à vendre

Comme pour énormément d'applications web, nous allons commencer par interroger une liste de données via une requête GET.

Tout d'abord, il faut dire à Angular qu'on souhaite utiliser des requêtes HTTP dans notre application. Dansapp.config.ts, il faut ajouterprovideHttpClient():

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(
      routes,
      withComponentInputBinding(),
      withInMemoryScrolling({ scrollPositionRestoration: 'enabled' })
    ),
    provideHttpClient()
  ]
};

Ensuite, dans le dossierhousing, je vous invite à créer un dossierserviceset un servicehousing.service.ts. Ce service pourra êtreprovidedIn: 'root', et injectera le fameux HttpClient :

import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class HousingService {
  private http = inject(HttpClient);
}

Vous pouvez maintenant créer une méthodegetAllProperties()qui utilisera la méthodeget()  du HttpClient :

getAllProperties() {
    return this.http.get('http://localhost:3030/api/properties');
}

Comme vous pouvez le constater, la méthodeget()peut être appelée avec simplement l'URL à appeler.

Pour utiliser cette nouvelle méthode, injectez HousingService dans PropertyListComponent (dans  housing/components/property-list) et créez un Observableproperties$:

export class PropertyListComponent {
  private housingService = inject(HousingService);
  properties$ = this.housingService.getAllProperties();
  protected readonly DUMMY_PROPERTIES = DUMMY_PROPERTIES;
}

Du coup, vous pouvez remplacerDUMMY_PROPERTIESdans la boucle@forpar une souscription à  properties$en important le pipeasync:

@for (property of properties$ | async; track property.id) {
    <app-property-list-card [property]="property"/>
}

Le problème que vous avez ici est que ni Angular ni TypeScript ne savent (pour l'instant) quel type d'objet est retourné par le serveur. Heureusement, c'est facile à réparer. Dans HousingService, ajoutez  HousingPropertyPreview[]comme paramètre de type à votre appel àget():

getAllProperties() {
    return this.http
        .get<HousingPropertyPreview[]>('http://localhost:3030/api/properties');
}

Ainsi, vous indiquez à TypeScript le type de réponse attendu — ça permet à Angular d'être certain, dans ce cas, de pouvoir boucler sur un tableau.

Avec ça, vous devriez voir d'autres biens — ceux du serveur — apparaître dans l'application !

Les biens présentés dans l'application ne sont plus les mêmes
De nouveaux biens

Comme dernière amélioration possible, vous pouvez utiliser@letdans le template pour souscrire à l'Observable et créer un alias global :

@let properties = properties$ | async;
<main class="property-list">
	<div class="property-grid">
		@for (property of properties; track property.id) {
			<app-property-list-card [property]="property"/>
		}
	</div>
</main>

Demandez des détails

Actuellement, si vous cliquez sur un bien, vous arrivez la page détail qui est codée en dur, c'est-à-dire que le bien affiché est statique et n'est pas celui que vous avez sélectionné :

Les détails d'un bien, mais pas celui sur lequel on a cliqué
Un bien… mais pas le bon

Danshousing/components/property-detail, vous trouverezPropertyDetailComponentqui, comme la vue liste précédemment, dépend deDUMMY_PROPERTIES. Mais ce n'est pas ce qu'on veut !

Comment faire pour récupérer les détails de ce bien ?

Premièrement, il faut récupérer l'idqui se trouve dans l'URL. Regardez la configuration de la route en question dansapp.routes.ts. La partie qui nous intéresse estpath: 'housing/:id'. Les deux-points:devantidl'identifient comme un paramètre de route.

Si vous regardez dansapp.config.ts, vous voyez la configuration suivante pour le router :

provideRouter(
    routes,
    withComponentInputBinding(),
    withInMemoryScrolling({ scrollPositionRestoration: 'enabled' })
),

L'appel àwithComponentInputBinding()fait que les paramètres de route peuvent être récupérés comme des inputs dans nos components !

Vous pouvez donc ajouter, dans PropertyDetailComponent :

export class PropertyDetailComponent {
  @Input() id!: string;
}

Et cet input reçoit automatiquement la valeur du paramètreid.

Il nous faut une méthode dansHousingServicequi prenne unidet qui l'utilise pour générer son URL de requête :

getPropertyById(id: string) {
    return this.http
        .get<HousingPropertyWithDetails>(`http://localhost:3030/api/properties/${id}`);
}

Remarquez qu'ici le type retourné par le serveur estHousingPropertyWithDetails.

On peut donc exploiter cette méthode dans notre component :

export class PropertyDetailComponent implements OnInit {
  private housingService = inject(HousingService);
  
  @Input() id!: string;
  property$!: Observable<HousingPropertyWithDetails>;

  ngOnInit() {
    this.property$ = this.housingService.getPropertyById(this.id);
  }
}

Avec ceci, vous pouvez wrap le template avec un@ifqui utilise cet Observable, le pipeasync, et qui crée un alias :

@if (property$ | async; as property) {
    <main class="property-details">
        <!-- ... -->
    </main>
}

Et voilà ! Quand on clique sur un bien, l'application en récupère les données et les affiche correctement :

En cliquant sur un bien, ce sont bien ses détails qui sont affichés
Le bon bien

À vous de jouer

Contexte

Vous souhaitez proposer aux utilisateurs de faire une offre sur le bien sélectionné. Le bouton sur la page détail renvoie versMakeOfferComponentoù, actuellement, le bien affiché est codé en dur. 

Consigne

Le bien affiché dansMakeOfferComponentdoit être récupéré depuis le serveur. Vous devrez :

  • récupérer l'  id  du bien affiché

  • utiliser cet  id  pour récupérer le bien

  • afficher le bien

En résumé

  • Utilisez provideHttpClient() et injectez HttpClient pour débloquer les requêtes HTTP.

  • Les requêtes HTTP en Angular sont des Observables qui :

    • émettent une fois et complètent lors d'une réponse positive ;

    • émettent une erreur (et sont donc détruits) lors d'une erreur serveur.

  • Les Observables générés par HttpClient envoient leur requête uniquement lorsqu'on souscrit à ces Observables ;

  • Souscrire à l'Observable HTTP avec le pipe  async  permet d'afficher facilement les données retournées par un serveur ;

  • La méthode  get  de HttpClient crée une requête GET à l'URL passée en argument.

Dans le prochain chapitre, vous créerez des requêtes composées, où la réponse d'une requête est utilisée automatiquement pour en déclencher une autre !

Et si vous obteniez un diplôme OpenClassrooms ?
  • Formations jusqu’à 100 % financées
  • Date de début flexible
  • Projets professionnalisants
  • Mentorat individuel
Trouvez la formation et le financement faits pour vous