Création des requêtes
backend/controllers/ingredient.js
exports.getOne = (req, res) => {
Ingredient.findOne({_id: req.params.id})
.then(ingredient => res.status(200).json(ingredient))
.catch(error => res.status(400).json(error));
}
exports.deleteOne = (req, res) => {
Ingredient.deleteOne({_id: req.params.id})
.then(ingredient => res.status(200).json(ingredient))
.catch(error => res.status(400).json(error));
}
Ce code définit deux fonctions pour le contrôleur des ingrédients dans un backend Express/Mongoose, permettant d’obtenir ou de supprimer un ingrédient spécifique selon son identifiant.
getOne
- Rôle : Cherche un ingrédient dans la base MongoDB dont l’identifiant (
_id) est celui transmis dans l’URL via les paramètres (req.params.id). - Succès : Retourne en réponse l’ingrédient sous forme d’objet JSON avec le code HTTP 200.
- Échec : Retourne l’erreur avec le code HTTP 400.
deleteOne
- Rôle : Supprime de la base MongoDB l’ingrédient dont l’identifiant (
_id) correspond à celui fourni dans les paramètres d’URL. - Succès : Retourne le résultat de la suppression (généralement un objet indiquant le nombre de documents supprimés) avec le code HTTP 200.
- Échec : Retourne l’erreur avec le code HTTP 400.
Mise à jour des routes
backend/routes/ingredient.js
router.delete('/:id', ingredientController.deleteOne);
router.get('/:id', ingredientController.getOne);
Mise à jour du front
frontend/shopping-list/src/app/ingredients/ingredients-list/ingredients-list.component.html
<span class="close" (click)="onRemoveIngredient(ingredient)" >X</span>
Mise à jour du composant
frontend/shopping-list/src/app/ingredients/ingredients-list/ingredients-list.component.ts
onRemoveIngredient(ingredient: Ingredient) {
const subscription = this.ingredientsService.removeIngredient(ingredient)
.subscribe({
next: (resData) => console.log(resData),
});
this.destroyRef.onDestroy(() => {
subscription.unsubscribe();
})
}
Cette méthode sert à supprimer un ingrédient via un service et à bien gérer la mémoire en évitant les fuites d’abonnement. Voici son fonctionnement détaillé :
- Appel du service
- Appelle la fonction
removeIngredientdu service, qui retourne un Observable (souvent lié à une requête HTTP de suppression vers l’API). - Abonne la méthode à la réponse (
subscribe). Quand l’opération réussit, le résultat (par exemple confirmation ou détail de la suppression) est affiché dans la console.
- Appelle la fonction
- Nettoyage de l’abonnement
- Utilise une référence à la destruction du composant (
destroyRef) pour être sûr qu’une fois le composant détruit (changement de page, fermeture, etc.), l’abonnement est bien coupé viaunsubscribe(). - Cela prévient les fuites mémoire et les comportements inattendus en cas de réponses tardives.
- Utilise une référence à la destruction du composant (
Appel des routes dans le service
frontend/shopping-list/src/app/shared/services/ingredients.service.ts
getIngredient(ingredient: Ingredient) {
return this.httpClient
.get('http://localhost:3200/api/ingredient/' + ingredient._id)
.pipe(
catchError(error => { return throwError(() => error)})
)
}
removeIngredient(ingredient: Ingredient) {
return this.httpClient
.delete('http://localhost:3200/api/ingredient/' + ingredient._id)
.pipe(
catchError((error) => {
return throwError(() => error)
})
)
}
- Ces méthodes facilitent la communication entre le frontend Angular et le backend Express.
- Elles respectent la gestion réactive des erreurs, ce qui simplifie le traitement côté composant.
- Le paramètre utilisé (
ingredient._id) garantit que l’action cible bien l’ingrédient voulu.
En résumé :
getIngredient appelle le backend pour obtenir un ingrédient spécifique, tandis que removeIngredient demande sa suppression, tout en gérant proprement les erreurs éventuelles et en retournant des Observables pour une intégration réactive dans Angular.
Création d’un signal output
frontend/shopping-list/src/app/ingredients/ingredients.component.ts
import { Ingredient } from './ingredient.model';
export class IngredientsComponent {
selectIngredient = output<Ingredient>();
}
output<Ingredient>() permet au composant d’envoyer des données (ici un ingrédient) vers le composant parent via un signal événementiel réactif, facilitant la communication inter-composants.
output<Ingredient>()crée un signal “output” du typeIngredient.- Cela permet au composant d’émettre un ingrédient vers son parent, typiquement lorsqu’un utilisateur effectue une action (ex : sélectionne un ingrédient dans une liste).
Comment ça marche ?
- Quand le composant veut avertir son parent qu’un ingrédient a été choisi, il fait
this.selectIngredient.emit(monIngredient); - Le parent peut alors écouter cet événement et réagir, comme avec l’ancien système des
@Output()etEventEmitter.
Cette syntaxe moderne, basée sur les signals, remplace le décorateur classique @Output(), offrant une approche plus réactive, plus propre et meilleure pour les performances avec Angular standalone.