Deux briques que tu croiseras dans chaque fichier Angular. Les décorateurs (@Component, @Injectable…) sont des cousins directs de tes attributs C#. Et l'asynchrone TypeScript (async/await/Promise) est quasi identique à ton Task. Encore une longueur d'avance.
@Component({...}). Chaque service est un @Injectable(). Tu ne peux pas lire — encore moins revoir — du code Angular sans savoir ce que ces @ font réellement. Et dès que tu touches à un appel réseau, à un chargement de route ou à une initialisation, l'asynchrone débarque. Ces deux notions sont le ticket d'entrée.
Un décorateur est une annotation que tu colles juste au-dessus d'une classe, d'une propriété ou d'une méthode avec la syntaxe @quelqueChose(...). Il attache des métadonnées et/ou modifie l'élément décoré. Angular lit ces métadonnées pour comprendre « cette classe est un composant, voici son template, voici ses dépendances ».
[HttpGet], [Authorize], [Serializable]. Tu décores une classe ou un membre, et un framework (ASP.NET, le sérialiseur…) lit l'info par réflexion pour adapter son comportement. Même position dans le code (au-dessus de l'élément), même but (« attacher une info que le framework va exploiter »). Une différence de fond plus bas — garde-la en tête.
Lis ce composant minimal. Chaque @ a un rôle précis :
import { Component, Input } from '@angular/core';
// @Component : « cette classe EST un composant ». Les métadonnées
// (sélecteur HTML, template) sont passées dans l'objet de config.
@Component({
selector: 'app-poste',
standalone: true,
template: `<h3>{{ nom }}</h3>`,
})
export class PosteComponent {
@Input() nom = ''; // @Input : ce champ est alimenté par le composant parent
}
| Décorateur | Sur quoi | Ce qu'il dit à Angular |
|---|---|---|
@Component | une classe | « C'est un composant : voici son sélecteur et son template » |
@Injectable | une classe | « Cette classe peut être injectée comme dépendance » (≈ service DI) |
@Input() | une propriété | « Cette donnée vient du parent » (entrée du composant) |
@Output() | une propriété | « Ce composant émet un événement vers le parent » |
@Component({...}), c'est l'appel Component({...}) qui retourne une fonction appliquée à ta classe. Il peut donc modifier ce qu'il décore, pas seulement l'étiqueter. En pratique avec Angular tu t'en sers comme des attributs — mais sache que le mécanisme est actif, pas déclaratif.
Promise = TaskUne Promise<T> représente une valeur qui arrivera plus tard : un appel réseau, un fichier, un timer. C'est le clone de ton Task<T> C#. Et la cerise : async/await s'écrivent exactement pareil.
// Récupère un poste depuis une API. Promise<PosteMesure> ≈ Task<PosteMesure>
async function chargerPoste(id: number): Promise<PosteMesure> {
const reponse = await fetch(`/api/postes/${id}`); // await, comme en C#
if (!reponse.ok) {
throw new Error('Poste introuvable'); // throw classique
}
return reponse.json(); // la valeur résolue de la Promise
}
// Appel : on await dans une autre fonction async, et on try/catch les erreurs
try {
const poste = await chargerPoste(1);
} catch (e) {
// gestion d'erreur, comme un catch sur un await Task
}
| TypeScript | Équivalent C# | Note |
|---|---|---|
Promise<T> | Task<T> | Une valeur future typée |
async / await | async / await | Identique au mot près |
.then(cb) | ContinueWith / await | L'ancienne façon, avant await |
.catch(cb) / try/catch | try/catch | Même logique d'erreur |
Promise.all([a, b]) | Task.WhenAll(a, b) | Attendre plusieurs en parallèle |
await : tu manipules alors la Promise elle-même (l'« enveloppe ») au lieu de sa valeur — exactement comme oublier d'await une Task en C#. (2) Lancer en série ce qui pourrait être parallèle : deux await à la suite alors qu'un Promise.all ferait les deux en même temps.
Tu viens de voir fetch + Promise, et c'est juste du TypeScript standard. Mais sache-le dès maintenant : pour les appels réseau, Angular privilégie les Observable (RxJS), pas les Promise. La différence en une phrase : une Promise livre une seule valeur, une fois ; un Observable est un flux qui peut en livrer zéro, une ou plusieurs, et qu'on peut annuler. On y consacrera des leçons entières (RxJS, phase 1). Les Promise restent bien présentes ailleurs : chargement de routes, import() dynamique, initialisation d'app. Donc tu dois maîtriser les deux.
@Component({...}) au-dessus d'une classe ?Task<T> correspond en TypeScript à…const poste = chargerPoste(1); sans await (la fonction renvoie une Promise). Que contient poste ?@X(...) attache des métadonnées à une classe/propriété (≈ attribut C#, mais c'est une fonction active). Les incontournables : @Component, @Injectable, @Input(), @Output(). Côté asynchrone, Promise<T> = Task<T> et async/await sont identiques à C# ; Promise.all = Task.WhenAll. Piège : un await oublié te laisse l'enveloppe. À venir : Angular préfère les Observable (RxJS) aux Promise pour le réseau.
MDN — Comment utiliser les promesses (en français). Lis l'intro, « then() et la gestion d'erreur », et « async et await ». C'est la base universelle, indépendante d'Angular.
Observable plutôt qu'une Promise sur tel appel ? Demande-moi, ici, maintenant.