À propos de ce cours
L’interpolation, ou opérateur moustache {{ }}, est la liaison de données la plus simple d’Angular. Apprenez ce qu’elle peut afficher, ce que le compilateur refuse et comment mettre en forme les valeurs avec les pipes, à travers une fiche de formation complète et six activités.
-
Objectifs
- Situer l'interpolation parmi les quatre liaisons de données (data binding) d'Angular
- Écrire des interpolations
{{ }}dans le texte et dans les attributs d'un template - Savoir ce qu'une interpolation peut contenir : propriétés, signaux, méthodes, opérateurs, ternaire,
?.,??, gabarits de chaîne, pipes - Connaître ce qui est interdit (affectation,
new,Math…) et lire les erreurs du compilateur - Mettre en forme les valeurs avec les pipes (
date,number,currency…) et la locale française - Comprendre que l'interpolation affiche du texte et protège contre l'injection de HTML
- Choisir entre une méthode et un
computedpour une valeur calculée
-
Présentation
- Un composant Angular a deux parties : une classe qui contient les données, et un template qui les affiche. Pour faire passer une valeur de la classe vers l'écran, Angular propose la liaison de données (data binding).
- Il existe quatre liaisons. L'interpolation est la première et la plus simple : elle affiche une valeur de la classe dans le template. On l'appelle aussi « opérateur moustache », car les doubles accolades
{{ }}ressemblent à une moustache vue de côté. - C'est une liaison à sens unique, de la classe vers la vue : l'interpolation lit une valeur, elle ne la modifie jamais.

-
Préparer le projet
- Créer un projet de test, puis un composant
fiche-formationqui servira d'exemple tout au long de la leçon :
- Créer un projet de test, puis un composant
ng new demo-interpolation --style=css --ssr=false
cd demo-interpolation
ng g c fiche-formation
ng g interface models/formation
- Toutes les sorties montrées dans la leçon ont été relevées dans le navigateur avec Angular 22.
-
La syntaxe de base
- On place une expression entre doubles accolades, n'importe où dans le texte du template. Angular l'évalue dans le contexte du composant, convertit le résultat en chaîne de caractères, et l'insère à la place des accolades.
- Les espaces à l'intérieur des accolades sont facultatifs :
{{titre}}et{{ titre }}sont équivalents ; la seconde écriture est la plus lisible.
import { Component, signal } from '@angular/core';
@Component({
selector: 'app-bienvenue',
template: `
<h2>Bienvenue chez {{ centre }}</h2>
<p>Formation : {{ titre() }}</p>
<p>Ouvert depuis {{ 2026 - anneeCreation }} ans</p>
`,
})
export class Bienvenue {
centre = 'FormaPlus';
anneeCreation = 2010;
titre = signal('Développement Angular');
}
<!-- Résultat dans le navigateur -->
<h2>Bienvenue chez FormaPlus</h2>
<p>Formation : Développement Angular</p>
<p>Ouvert depuis 16 ans</p>

- Un signal se lit avec des parenthèses :
{{ titre() }}. Écrire{{ titre }}afficherait la fonction elle-même ; le compilateur le signale par un avertissementNG8109: titre is a function and should be invoked: titre().
-
Interpoler dans un attribut
- L'interpolation fonctionne aussi dans la valeur d'un attribut HTML. Angular la transforme en liaison de propriété.
<img src="/images/{{ formation().code }}.svg"
alt="Illustration de la formation {{ formation().titre }}" />
<p title="Formation {{ titre() }}">Survolez-moi</p>
- Résultat réel :
src="/images/ANG.svg",alt="Illustration de la formation Développement Angular". - Quand l'attribut ne contient que l'expression, on préfère la liaison de propriété
[src]="image()", étudiée dans la leçon suivante. L'interpolation est pratique quand on mélange du texte fixe et une valeur, comme dansaltci-dessus.
-
Ce que l'interpolation affiche
- Le résultat de l'expression est toujours converti en texte. Voici ce que l'on obtient selon le type de la valeur :

nulletundefineddeviennent une chaîne vide : pas de texte « null » à l'écran.- Un objet affiche
[object Object]: il faut afficher une de ses propriétés ({{ objet.nom }}) ou, pour déboguer, utiliser le pipejson. - Une date ou un nombre s'affichent sans mise en forme : ce sera le rôle des pipes.
-
Les expressions autorisées
- Une interpolation contient une expression: un morceau de code qui produit une valeur. Angular accepte la plupart des expressions JavaScript :
| Expression | Exemple | Résultat |
|---|---|---|
| propriété, signal, accesseur | {{ centre }}, {{ titre() }}, {{ anciennete }} |
FormaPlus, Développement Angular, 16 |
| opérations | {{ nombre * 1.19 }} |
1428 |
| méthode du composant | {{ saluer('Sami') }} |
Bonjour Sami |
| ternaire | {{ vrai ? 'oui' : 'non' }} |
oui |
| chaînage optionnel et valeur par défaut | {{ formateur?.nom ?? 'à définir' }} |
à définir |
| propriétés et méthodes JavaScript | {{ tableau.length }}, {{ tableau.join(' / ') }} |
3, HTML / CSS / TS |
| comparaisons et opérateurs logiques | {{ texte.length > 5 && vrai }} |
true |
| gabarit de chaîne (template literal) | {{ `Session : ${texte} (${nombre} DT)` }} |
Session : Angular (1200 DT) |
typeof, puissance **, in |
{{ typeof nombre }}, {{ 2 ** 10 }}, {{ 'nom' in objet }} |
number, 1024, true |
| pipe | {{ texte | uppercase }} |
ANGULAR |
- Les gabarits de chaîne,
typeof,**etinne sont acceptés dans les templates que depuis les dernières versions d'Angular (19 à 20). Dans un projet ancien, ils provoquent une erreur de compilation.
-
Les expressions interdites
- Une interpolation sert à lire, jamais à modifier. Elle ne voit que les membres du composant : pas les objets globaux du navigateur.
- Le compilateur refuse :
- les affectations :
=,+=,++,--; - les instructions multiples séparées par
;; new;- les objets globaux :
Math,Date,window,document,console; - les opérateurs binaires
|et&(le|est réservé aux pipes).
- les affectations :

- Pour utiliser
Mathou créer une date, on passe par le composant : une propriété, uncomputedou une méthode.
<!-- ✘ refusé -->
<p>{{ Math.round(moyenne) }}</p>
<!-- ✔ accepté -->
<p>{{ moyenneArrondie() }}</p>
moyenne = signal(14.666);
moyenneArrondie = computed(() => Math.round(this.moyenne()));
-
Mettre en forme avec les pipes
- Un pipe transforme une valeur juste avant son affichage. Il s'écrit après une barre verticale
|, avec ses paramètres après des deux-points:. Les pipes s'enchaînent :{{ titre() | slice: 0 : 10 | uppercase }}. - Chaque pipe utilisé doit être importé dans le composant (
DatePipe,DecimalPipe,CurrencyPipe,PercentPipe,UpperCasePipe…), sinon :NG8004: No pipe found with name 'date'.
- Un pipe transforme une valeur juste avant son affichage. Il s'écrit après une barre verticale

- Par défaut, Angular met en forme les nombres et les dates en anglais américain. Pour le format français (espace des milliers, virgule décimale, jours en français), on enregistre la locale française dans
app.config.ts:
// src/app/app.config.ts
import { ApplicationConfig, LOCALE_ID, provideBrowserGlobalErrorListeners } from '@angular/core';
import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr';
registerLocaleData(localeFr);
export const appConfig: ApplicationConfig = {
providers: [provideBrowserGlobalErrorListeners(), { provide: LOCALE_ID, useValue: 'fr-FR' }],
};
- Les pipes sont détaillés dans la leçon consacrée aux pipes. Ici, retenez qu'ils sont la bonne façon de mettre en forme une valeur pour l'affichage, sans modifier la donnée dans la classe.
-
Exemple complet : la fiche d'une formation
- On assemble tout dans le composant
FicheFormation: le modèle, les signaux et valeurs calculées dans la classe, et uniquement des interpolations dans le template.
- On assemble tout dans le composant
// src/app/models/formation.ts
export interface Formateur {
prenom: string;
nom: string;
}
export interface Formation {
code: string;
titre: string;
niveau: 'Débutant' | 'Intermédiaire' | 'Avancé';
dureeHeures: number;
prixHT: number;
dateDebut: Date;
places: number;
inscrits: number;
formateur: Formateur | null;
modules: string[];
}
<!-- fiche-formation.html -->
<article class="fiche">
<img src="/images/{{ formation().code }}.svg" alt="Illustration de la formation {{ formation().titre }}" />
<div class="infos">
<span class="niveau">{{ formation().niveau | uppercase }}</span>
<h2>{{ formation().titre }}</h2>
<p>Code {{ formation().code }} · {{ formation().dureeHeures }} heures · {{ formation().modules.length }} modules</p>
<p>Début : {{ formation().dateDebut | date: 'EEEE d MMMM y' }}</p>
<p>Formateur : {{ formation().formateur?.prenom ?? 'à définir' }} {{ formation().formateur?.nom }}</p>
<p class="prix">{{ formation().prixHT | number: '1.3-3' }} DT HT · {{ prixTTC() | currency: 'TND' }} TTC</p>
<p class="places">
{{ placesRestantes() }} {{ placesRestantes() > 1 ? 'places restantes' : 'place restante' }}
– remplie à {{ tauxRemplissage() | percent }}
</p>
<p class="modules">{{ formation().modules.join(' · ') }}</p>
<button type="button" (click)="suivante()">Formation suivante</button>
</div>
</article>
// src/app/fiche-formation/fiche-formation.ts
import { Component, computed, signal } from '@angular/core';
import { CurrencyPipe, DatePipe, DecimalPipe, PercentPipe, UpperCasePipe } from '@angular/common';
import { Formation } from '../models/formation';
@Component({
selector: 'app-fiche-formation',
imports: [CurrencyPipe, DatePipe, DecimalPipe, PercentPipe, UpperCasePipe],
styleUrl: './fiche-formation.css',
templateUrl: './fiche-formation.html',
})
export class FicheFormation {
private readonly formations: Formation[] = [
{
code: 'ANG', titre: 'Développement Angular', niveau: 'Intermédiaire', dureeHeures: 120,
prixHT: 1200, dateDebut: new Date(2026, 10, 2), places: 20, inscrits: 14,
formateur: { prenom: 'Ali', nom: 'Gharbi' },
modules: ['TypeScript', 'Composants', 'Liaisons', 'Services', 'Routage'],
},
{
code: 'FLU', titre: 'Développement mobile Flutter', niveau: 'Avancé', dureeHeures: 100,
prixHT: 1100, dateDebut: new Date(2026, 11, 7), places: 12, inscrits: 11,
formateur: null,
modules: ['Dart', 'Widgets', 'MVVM'],
},
];
readonly tva = 0.19;
readonly index = signal(0);
readonly formation = computed(() => this.formations[this.index()]);
readonly prixTTC = computed(() => this.formation().prixHT * (1 + this.tva));
readonly placesRestantes = computed(() => this.formation().places - this.formation().inscrits);
readonly tauxRemplissage = computed(() => this.formation().inscrits / this.formation().places);
suivante(): void {
this.index.update((i) => (i + 1) % this.formations.length);
}
}
- Les images
ANG.svgetFLU.svgsont placées danspublic/images/. Le fichier CSS et les images sont fournis dans le projet téléchargeable.

- Relevez dans le template les différentes formes d'interpolation : signal (
formation().titre), interpolation dans des attributs (src,alt), pipes avec paramètres, chaînage optionnel avec valeur par défaut (formateur absent), ternaire (singulier ou pluriel), méthode JavaScript (join). - Un clic sur « Formation suivante » change un seul signal (
index) : toutes les valeurs qui en dépendent sont recalculées, et Angular met à jour les textes concernés.
-
L'interpolation et la sécurité
- L'interpolation affiche toujours du texte. Si la valeur contient des balises HTML, elles sont affichées telles quelles, et non interprétées. C'est une protection contre l'injection de code (XSS) : un commentaire saisi par un utilisateur ne peut pas exécuter de script.
- Pour afficher du HTML volontairement, on utilise la liaison
[innerHTML]. Angular nettoie alors le contenu (il supprime par exemple l'attributonerror) et prévient dans la console.

-
Méthode ou computed ?
- Une interpolation est réévaluée à chaque vérification du composant. Si elle appelle une méthode, celle-ci est donc rappelée à chaque clic, même quand rien n'a changé. Un
computed, lui, garde son résultat en mémoire et ne se recalcule que si un signal qu'il lit a changé.
- Une interpolation est réévaluée à chaque vérification du composant. Si elle appelle une méthode, celle-ci est donc rappelée à chaque clic, même quand rien n'a changé. Un

- Pour une valeur calculée (prix TTC, moyenne, total), préférez un
computed. - Une méthode simple et rapide reste acceptable ; évitez en revanche une méthode lente (boucle sur une grande liste, tri…) dans une interpolation.
-
Bonnes pratiques
- Garder des expressions courtes et simples: la logique va dans la classe (un
computed), pas dans le template. - Ne jamais produire d'effet de bord dans une interpolation : elle doit seulement lire.
- Mettre en forme avec des pipes plutôt qu'avec
toFixed()ou des concaténations. - Utiliser
?.et??pour les valeurs qui peuvent manquer. - Ne pas oublier les parenthèses pour lire un signal :
{{ titre() }}.
- Garder des expressions courtes et simples: la logique va dans la classe (un
-
Activité 1 : premières interpolations
- Dans le projet
demo-interpolation, créer un composantcarte-visitequi affiche un nom, une fonction, un e-mail et l'âge calculé à partir d'une année de naissance. - Afficher le nom en majuscules avec un pipe, et l'e-mail dans l'attribut
titled'un paragraphe.
- Dans le projet
-
Activité 2 : conversions
- Afficher successivement :
null,undefined, un tableau, un objet, une date et un booléen. Noter chaque résultat et le comparer au tableau de la leçon. - Corriger l'affichage de l'objet et de la date avec les bons pipes.
- Afficher successivement :
-
Activité 3 : expressions interdites
- Écrire une par une les interpolations
{{ total = 0 }},{{ compteur++ }},{{ Math.max(a, b) }}et{{ new Date() }}. Noter le code et le message de chaque erreur. - Réécrire chaque besoin correctement en passant par la classe du composant.
- Écrire une par une les interpolations
-
Activité 4 : la fiche formation en français
- Reproduire le composant
FicheFormation, puis configurer la locale française et vérifier les formats des prix, des dates et des pourcentages. - Ajouter une troisième formation sans aucun module, et afficher « Programme à venir » quand la liste est vide (ternaire).
- Reproduire le composant
-
Activité 5 : méthode ou computed
- Reproduire l'exemple
prixTTC()et observer le nombre d'appels dans la console à chaque clic. - Remplacer la méthode par un
computedet refaire le test. Expliquer la différence en deux phrases.
- Reproduire l'exemple
-
Activité 6 : retour sur le projet FormaPlus
- Dans votre projet
forma-plus, remplacer les valeurs écrites en dur dans les templates (nom du centre, année, coordonnées) par des interpolations de propriétés ou de signaux du composant. - Faire un commit :
git commit -m "Interpolation : données affichées depuis les composants", puis un push.
- Dans votre projet
-
Erreurs fréquentes

| Message | Cause | Solution |
|---|---|---|
NG5002: Parser Error: Bindings cannot contain assignments |
affectation dans l'interpolation | modifier la valeur dans une méthode de la classe |
NG5002: Parser Error: Unexpected end of expression |
++ ou -- |
idem |
NG5002: … Binding expression cannot contain chained expression |
plusieurs instructions séparées par ; |
une seule expression |
TS2339: Property 'Math' does not exist on type '…' |
objet global utilisé (Math, console, window) |
passer par un computed ou une méthode |
TS2339: Property 'prenom' does not exist on type '…' |
faute de frappe ou propriété absente | corriger le nom ou ajouter la propriété |
NG8109: titre is a function and should be invoked: titre() (avertissement) |
signal lu sans parenthèses | écrire {{ titre() }} |
NG8004: No pipe found with name 'date'. |
pipe non importé | l'ajouter aux imports du composant |
[object Object] affiché |
objet entier interpolé | afficher une propriété, ou | json pour déboguer |
-
À retenir
- L'interpolation
{{ expression }}affiche une valeur de la classe dans le template : liaison à sens unique, classe → vue. - Elle fonctionne dans le texte et dans les valeurs d'attributs.
- Le résultat est converti en texte ;
nulletundefineddeviennent une chaîne vide. - Expressions permises : propriétés, signaux (avec
()), méthodes, opérateurs, ternaire,?.,??, gabarits de chaîne, pipes. - Interdit : affectations,
++,;,new, objets globaux. - Les pipes mettent en forme ;
LOCALE_IDdonne le format français. - Le HTML interpolé n'est jamais interprété : protection contre l'injection de code.
- Pour une valeur calculée, préférer un
computedà une méthode.
- L'interpolation
L'opérateur moustache est une fenêtre sur la classe : il montre les données, sans jamais y toucher.