Vous êtes sur la page 1sur 62

Deviens un ninja avec Angular2 (extrait

gratuit)
Ninja Squad
Table of Contents
1. Extrait gratuit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
2. Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
3. Une rapide introduction ECMASCRIPT6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.1. Transpileur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.2. let . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.3. Constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.4. Cration dobjets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.5. Affectations dstructures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.6. Paramtres optionnels et valeurs par dfaut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.7. Rest operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.8. Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.9. Promises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.10. (arrow functions) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.11. Set et Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.12. Template de string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.13. Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.14. Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4. Un peu plus loin quES6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.1. Types dynamiques, statiques et optionnels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.2. Hello TypeScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.3. Un exemple concret dinjection de dpendance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
5. Dcouvrir TypeScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.1. Les types de TypeScript. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.2. Valeurs numres (enum) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.3. Return types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.4. Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
5.5. Paramtre optionnel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5.6. Des fonctions en proprit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5.7. Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
5.8. Utiliser dautres bibliothques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
5.9. Decorateurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
6. Le monde merveilleux des Web Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
6.1. Le nouveau Monde . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
6.2. Custom elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
6.3. Shadow DOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
6.4. Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
6.5. HTML imports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
6.6. Polymer et X-tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
7. La philosophie dAngular2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
8. Commencer de zro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
8.1. Crer une application avec TypeScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
8.2. Notre premier composant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
8.3. Dmarrer lapplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
8.4. Commencer de zro avec angular-cli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
9. Fin de lextrait gratuit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Chapter 1. Extrait gratuit
Ce que tu vas lire ici est un extrait gratuit: cest le dbut du livre, qui explique son but et son
contenu, donne un aperu dECMAScript6, TypeScript, et des Web Components, dcrit la
philosophie dAngular2, puis te propose de construire ta premire application.

Cet extrait ne demande aucune connaissance prliminaire.

1
Chapter 2. Introduction
Alors comme a on veut devenir un ninja?! a tombe bien, tu es entre de bonnes mains!

Mais pour y parvenir, nous avons un bon bout de chemin parcourir ensemble, sem dembches et
de connaissances acqurir :).

On vit une poque excitante pour le dveloppement web. Il y a un nouvel Angular, une rcriture
complte de ce bon vieil AngularJS. Pourquoi une rcriture complte? AngularJS1.x ne suffisait-il
donc pas?

Jadore cet ancien AngularJS. Dans notre petite entreprise, on la utilis pour construire plusieurs
projets, on a contribu du code au cur du framework, on a form des centaines de dveloppeurs (oui,
des centaines, littralement), et on a mme crit un livre sur le sujet.

AngularJS est incroyablement productif une fois matris. Mais cela ne nous empche pas de constater
ses faiblesses. AngularJS nest pas parfait, avec des concepts trs difficiles cerner, et des piges durs
viter.

Et qui plus est, le web a bien volu depuis quAngularJS a t conu. JavaScript a chang. De nouveaux
frameworks sont apparus, avec de belles ides, ou de meilleures implmentations. Nous ne sommes
pas le genre de dveloppeurs te conjurer dutiliser tel outil plutt que tel autre. Nous connaissons
juste trs bien quelques outils, et savons ce qui peut correspondre au projet. AngularJS tait un de ces
outils, qui nous permettait de construire des applications web bien testes, et de les construire vite. On
a aussi essay de le plier quand il ntait pas forcment loutil idal. Merci de ne pas nous condamner,
a arrive aux meilleurs dentre nous, nest-ce pas? ;p

Angular2 sera-t-il loutil que lon utilisera sans aucune hsitation dans nos projets futurs? Cest dur
dire pour le moment, parce que ce framework est encore tout jeune, et que son cosystme est peine
bourgeonnant.

En tout cas, Angular2 a beaucoup de points positifs, et une vision dont peu de frameworks peuvent se
targuer. Il a t conu pour le web de demain, avec ECMAScript6, les Web Components, et le mobile en
tte. Quand il a t annonc, jai dabord t triste, comme beaucoup de gens, que cette version 2.0
nallait pas tre une simple volution (et dsol si tu viens de lapprendre).

Mais jtais aussi trs curieux de voir quelles ides allait apporter la talentueuse quipe de Google.

Alors jai commenc crire ce livre, ds les premiers commits, lisant les documents de conception,
regardant les vidos de confrences, et analysant chaque commit depuis le dbut. Javais crit mon
premier livre sur AngularJS1.x quand ctait dj un animal connu et bien apprivois. Ce livre-ci est
trs diffrent, commenc quand rien ntait encore clair dans la tte mme des concepteurs. Parce que
je savais que jallais apprendre beaucoup, sur Angular videmment, mais aussi sur les concepts qui
allaient dfinir le futur du dveloppement web, et certains nont rien voir avec Angular. Et ce fut le
cas. Jai du creuser pas mal, et jespre que tu vas apprcier revivre ces dcouvertes avec moi, et
comprendre comment ces concepts sarticulent avec Angular.

2
Lambition de cet ebook est dvoluer avec Angular. Sil savre quAngular devient le grand framework
quon espre, tu en recevras des mises jour avec des bonnes pratiques et de nouvelles fonctionnalits
quand elles mergeront (et avec moins de fautes de frappe, parce quil en reste probablement malgr
nos nombreuses relectures). Et jadorerais avoir tes retours, si certains chapitres ne sont pas assez
clairs, si tu as repr une erreur, ou si tu as une meilleure solution pour certains points.

Je suis cependant assez confiant sur nos exemples de code, parce quils sont extraits dun vrai projet, et
sont couverts par des centaines de tests unitaires. Ctait la seule faon dcrire un livre sur un
framework en gestation, et de reprer les problmes qui arrivaient invitablement avec chaque
release.

Mme si au final tu nes pas convaincu par Angular, je suis peu prs sr que tu vas apprendre deux-
trois trucs en chemin.

Si tu as achet le "pack pro" (merci!), tu pourras construire une petite application morceau par
morceau, tout au long du livre. Cette application sappelle PonyRacer, cest un site web o tu peux
parier sur des courses de poneys. Tu peux mme tester cette application ici! Vas-y, je tattend.

Cool, non?

Mais en plus dtre super cool, cest une application complte. Tu devras crire des composants, des
formulaires, des tests, tu devras utiliser le routeur, appeler une API HTTP (fournie), et mme faire des
Web Sockets. Elle intgre tous les morceaux dont tu auras besoin pour construire une vraie
application.

Chaque exercice viendra avec son squelette, un ensemble dinstructions et quelques tests. Quand tu
auras tous les tests en succs, tu auras termin lexercice!

Si tu nas pas achet le "pack pro" (tu devrais), ne tinquite pas: tu apprendras tout ce dont tu auras
besoin. Mais tu ne construiras pas cette application incroyable avec de beaux poneys en pixel art. Quel
dommage :)!

Tu te rendras vite compte quau-del dAngular, nous avons essay dexpliquer les concepts au cur
du framework. Les premiers chapitres ne parlent mme pas dAngular: ce sont ceux que jappelle les
"chapitres conceptuels", ils te permettront de monter en puissance avec les nouveauts intressantes
de notre domaine.

Ensuite, nous construirons progressivement notre connaissance du framework, avec les composants,
les templates, les pipes, les formulaires, http, le routeur, les tests

Et enfin, nous nous attaquerons quelques sujets avancs. Mais cest une autre histoire.

Passons cette trop longue introduction, et jetons-nous sur un sujet qui va dfinitivement changer notre
faon de coder: ECMAScript6.

3
Chapter 3. Une rapide introduction
ECMASCRIPT6
Si tu lis ce livre, on peut imaginer que tu as dj entendu parler de JavaScript. Ce quon appelle
JavaScript (JS) est une des implmentations dune spcification standardise, appele ECMAScript. La
version de la spcification que tu connais le plus est probablement la version 5: cest celle utilise
depuis de nombreuses annes.

Depuis quelques temps, une nouvelle version de cette spcification est en travaux: ECMASCRIPT6,
ES6, ou ECMASCRIPT2015. Je lappellerai dsormais systmatiquement ES6, parce que cest son petit
nom le plus populaire. Elle ajoute une tonne de fonctionnalits JavaScript, comme les classes, les
constantes, les arrow functions, les gnrateurs Il y a tellement de choses quon ne peut pas tout
couvrir, sauf y consacrer entirement ce livre. Mais Angular2 a t conu pour bnficier de cette
nouvelle version de JavaScript. Mme si tu peux toujours utiliser ton bon vieux JavaScript, tu auras
plein davantages utiliser ES6. Ainsi, nous allons consacrer ce chapitre dcouvrir ES6, et voir
comment il peut nous tre utile pour construire une application Angular2.

On va laisser beaucoup daspects de ct, et on ne sera pas exhaustifs sur ce quon verra. Si tu connais
dj ES6, tu peux directement sauter ce chapitre. Sinon, tu vas apprendre des trucs plutt incroyables
qui te serviront lavenir mme si tu nutilises finalement pas Angular!

3.1. Transpileur
ES6 vient datteindre son tat final, il nest pas encore support par tous les navigateurs. Et bien sr,
certains navigateurs vont tre en retard (est-il vraiment ncessaire de les nommer? :p). Ainsi, quoi
bon prsenter cela sil faut tre prudent sur ce quon peut utiliser ou non? Et tu as raison, car rares
sont les applications qui peuvent se permettre dignorer les navigateurs devenus obsoltes. Mais
comme tous les dveloppeurs qui ont essay ES6 ont hte de lutiliser dans leurs applications, la
communaut a trouv une solution: un transpileur.

Un transpileur prend du code source ES6 en entre et gnre du code ES5, qui peut tourner dans
nimporte quel navigateur. Il gnre mme les fichiers source map, qui permettent de dbugger
directement le code ES6 depuis le navigateur. Au moment de lcriture de ces lignes, il y a deux outils
principaux pour transpiler de lES6:

Traceur, un projet Google.

Babeljs, un projet dmarr par Sebastian McKenzie, un jeune dveloppeur de 17 ans (oui, a fait
mal), et qui a reu beaucoup de contributions extrieures.

Chacun a ses avantages et ses inconvnients. Par exemple Babeljs produit un code source plus lisible
que Traceur. Mais Traceur est un projet Google, alors videmment, Angular et Traceur vont bien
ensemble. Le code source dAngular2 tait dailleurs transpil avec Traceur, avant de basculer en
TypeScript.

4
Pour parler franchement, Babel est biiiiien plus populaire que Traceur, on aurait donc tendance te le
conseiller. Le projet devient peu peu le standard de-facto.

Si tu veux jouer avec ES6, ou le mettre en place dans un de tes projets, jette un il ces transpileurs, et
ajoute une tape la construction de ton projet. Elle prendra tes fichiers sources ES6 et gnrera
lquivalent en ES5. a fonctionne trs bien mais, videmment, certaines fonctionnalits nouvelles sont
difficiles ou impossibles transformer, parce quelles nexistent tout simplement pas en ES5.
Nanmoins ltat davancement actuel de ces transpileurs est largement suffisant pour les utiliser sans
se faire de souci, alors jetons un coup dil ces nouveauts ES6.

3.2. let
Si tu fais du JS depuis quelques temps, tu sais que la dclaration de variable avec var peut tre dlicate.
Dans peu prs tous les autres langages, une variable existe partir de la ligne contenant la
dclaration de cette variable. Mais en JS, il y a un concept nomm hoisting ("remonte") qui dclare la
variable au tout dbut de la fonction, mme si tu las crite plus loin.

Ainsi, dclarer une variable name dans le bloc if:

function getPonyFullName(pony) {
if (pony.isChampion) {
var name = 'Champion ' + pony.name;
return name;
}
return pony.name;
}

est quivalent la dclarer tout en haut de la fonction:

function getPonyFullName(pony) {
var name;
if (pony.isChampion) {
name = 'Champion ' + pony.name;
return name;
}
// name is still accessible here,
// and can have a value from the if block
return pony.name;
}

ES6 introduit un nouveau mot-cl pour la dclaration de variable, let, qui se comporte enfin comme
on pourrait sy attendre:

5
function getPonyFullName(pony) {
if (pony.isChampion) {
let name = 'Champion ' + pony.name;
return name;
}
// name is not accessible here
return pony.name;
}

Laccs la variable name est maintenant restreint son bloc. let a t pens pour remplacer
dfinitivement var long terme, donc tu peux abandonner ce bon vieux var au profit de let. La bonne
nouvelle est que a doit tre indolore, et que si a ne lest pas, cest que tu as mis le doigt sur un dfaut
de ton code!

3.3. Constantes
Tant quon est sur le sujet des nouveaux mot-cls et des variables, il y en a un autre qui peut tre
intressant. ES6 introduit aussi const pour dclarer des constantes! Si tu dclares une variable avec
const, elle doit obligatoirement tre initialise, et tu ne pourras plus lui affecter de nouvelle valeur par
la suite.

const PONIES_IN_RACE = 6;

PONIES_IN_RACE = 7; // SyntaxError

Jai utilis ici lcriture en snake_case, en MAJUSCULE, pour nommer la constante, comme on le ferait
en Java. Il ny a aucune obligation le faire, mais a semble naturel davoir une convention dcriture
pour les constantes: trouve la tienne et tiens-y-toi!

Comme pour les variables dclares avec let, les constantes ne sont pas hoisted ("remontes") et sont
bien dclares dans leur bloc.

Il y a un dtail qui peut cependant surprendre le profane. Tu peux initialiser une constante avec un
objet et modifier par la suite le contenu de lobjet.

const PONY = { };
PONY.color = 'blue'; // works

Mais tu ne peux pas assigner la constante un nouvel objet:

6
const PONY = { };

PONY = {color: 'blue'}; // SyntaxError

Mme chose avec les tableaux:

const PONIES = [];


PONIES.push({ color: 'blue' }); // works

PONIES = []; // SyntaxError

3.4. Cration dobjets


Ce nest pas un nouveau mot-cl, mais a peut te faire tiquer en lisant du code ES6. Il y a un nouveau
raccourci pour crer des objets, quand la proprit de lobjet que tu veux crer a le mme nom que la
variable utilise comme valeur pour lattribut.

Exemple:

function createPony() {
let name = 'Rainbow Dash';
let color = 'blue';
return { name: name, color: color };
}

peut tre simplifi en:

function createPony() {
let name = 'Rainbow Dash';
let color = 'blue';
return { name, color };
}

3.5. Affectations dstructures


Celui-l aussi peut te faire tiquer en lisant du code ES6. Il y a maintenant un raccourci pour affecter
des variables partir dobjets ou de tableaux.

En ES5:

7
var httpOptions = { timeout: 2000, isCache: true };
// later
var httpTimeout = httpOptions.timeout;
var httpCache = httpOptions.isCache;

Maintenant, en ES6, tu peux crire:

let httpOptions = { timeout: 2000, isCache: true };


// later
let { timeout: httpTimeout, isCache: httpCache } = httpOptions;

Et tu auras le mme rsultat. Ca peut tre perturbant, parce que la cl est la proprit lire dans lobjet
et la valeur est la variable affecter. Mais a fonctionne bien! Et mme mieux: si la variable que tu
veux affecter a le mme nom que la proprit de lobjet lire, tu peux crire simplement:

let httpOptions = { timeout: 2000, isCache: true };


// later
let { timeout, isCache } = httpOptions;
// you now have a variable named 'timeout'
// and one named 'isCache' with correct values

Le truc cool est que a marche aussi avec des objets imbriqus:

let httpOptions = { timeout: 2000, cache: { age: 2 } };


// later
let { cache: { age } } = httpOptions;
// you now have a variable named 'age' with value 2

Et la mme chose est possible avec des tableaux:

let timeouts = [1000, 2000, 3000];


// later
let [shortTimeout, mediumTimeout] = timeouts;
// you now have a variable named 'shortTimeout' with value 1000
// and a variable named 'mediumTimeout' with value 2000

Et bien sr a fonctionne avec des tableaux de tableaux, des tableaux dans des objets, etc

Cette fonctionnalit est pratique pour dclarer plusieurs variables partir dun objet retourn par une
fonction. Imagine une fonction randomPonyInRace qui retourne un poney et sa position dans la course.

8
function randomPonyInRace() {
let pony = { name: 'Rainbow Dash' };
let position = 2;
// ...
return { pony, position };
}
let { position, pony } = randomPonyInRace();

Cette nouvelle fonctionnalit de dstructuration assigne la position retourne par la mthode la


variable position, et le poney la variable pony. Et si tu nas pas usage de la position, tu peux crire:

function randomPonyInRace() {
let pony = { name: 'Rainbow Dash' };
let position = 2;
// ...
return { pony, position };
}
let { pony } = randomPonyInRace();

Et tu auras seulement une variable pony.

3.6. Paramtres optionnels et valeurs par dfaut


JS a la particularit de permettre aux dveloppeurs dappeler une fonction avec un nombre
darguments variable:

si tu passes plus darguments que dclars par la fonction, les arguments supplmentaires sont tout
simplement ignors (pour tre tout fait exact, tu peux quand mme les utiliser dans la fonction
avec la variable spciale arguments).

si tu passes moins darguments que dclars par la fonction, les paramtres manquants auront la
valeur undefined.

Ce dernier cas est celui qui nous intresse. Souvent, on passe moins darguments quand les paramtres
sont optionnels, comme dans lexemple suivant:

function getPonies(size, page) {


size = size || 10;
page = page || 1;
// ...
server.get(size, page);
}

Les paramtres optionnels ont la plupart du temps une valeur par dfaut. Loprateur OR (||) va

9
retourner loprande de droite si celui de gauche est undefined, comme a serait le cas si le paramtre
na pas t fourni par lappelant (pour tre prcis, si loprande de gauche est falsy, cest--dire
undefined, 0, false, "", etc). Avec cette astuce, la fonction getPonies peut ainsi tre invoque:

getPonies(20, 2);
getPonies(); // same as getPonies(10, 1);
getPonies(15); // same as getPonies(15, 1);

Cela fonctionnait, mais ce ntait pas vident de savoir que les paramtres taient optionnels, sauf
lire le corps de la fonction. ES6 offre dsormais une faon plus formelle de dclarer des paramtres
optionnels, ds la dclaration de la fonction:

function getPonies(size = 10, page = 1) {


// ...
server.get(size, page);
}

Maintenant il est limpide que la valeur par dfaut de size sera 10 et celle de page sera 1 sils ne sont pas
fournis.

Il y a cependant une subtile diffrence, car maintenant 0 ou "" sont des valeurs valides,
NOTE et ne seront pas remplaces par les valeurs par dfaut, comme size = size || 10
laurait fait. Cest donc plutt quivalent size = size === undefined ? 10: size;.

La valeur par dfaut peut aussi tre un appel de fonction:

function getPonies(size = defaultSize(), page = 1) {


// the defaultSize method will be called if size is not provided
// ...
server.get(size, page);
}

ou mme dautres variables, dautres variables globales, ou dautres paramtres de la mme fonction:

function getPonies(size = defaultSize(), page = size - 1) {


// if page is not provided, it will be set to the value
// of the size parameter minus one.
// ...
server.get(size, page);
}

Note que si tu essayes dutiliser des paramtres sur la droite, leur valeur sera toujours undefined:

10
function getPonies(size = page, page = 1) {
// size will always be undefined, as the page parameter is on its right.
server.get(size, page);
}

Ce mcanisme de valeur par dfaut ne sapplique pas quaux paramtres de fonction, mais aussi aux
valeurs de variables, par exemple dans le cas dune affectation dstructure:

let { timeout = 1000 } = httpOptions;


// you now have a variable named 'timeout',
// with the value of 'httpOptions.timeout' if it exists
// or 1000 if not

3.7. Rest operator


ES6 introduit aussi une nouvelle syntaxe pour dclarer un nombre variable de paramtres dans une
fonction. Comme on le disait prcdemment, tu peux toujours passer des arguments supplmentaires
un appel de fonction, et y accder avec la variable spciale arguments. Tu peux faire quelque chose
comme:

function addPonies(ponies) {
for (var i = 0; i < arguments.length; i++) {
poniesInRace.push(arguments[i]);
}
}
addPonies('Rainbow Dash', 'Pinkie Pie');

Mais tu seras daccord pour dire que ce nest ni lgant, ni vident: le paramtre ponies nest jamais
utilis, et rien nindique quon peut fournir plusieurs poneys.

ES6 propose une syntaxe bien meilleure, grce au rest operator ("oprateur de reste").

function addPonies(...ponies) {
for (let pony of ponies) {
poniesInRace.push(pony);
}
}

ponies est dsormais un vritable tableau, sur lequel on peut itrer. La boucle for of utilise pour
litration est aussi une nouveaut dES6. Elle permet dtre sr de nitrer que sur les valeurs de la
collection, et non pas sur ses proprits comme for in. Ne trouves-tu pas que notre code est

11
maintenant bien plus beau et lisible?

Le rest operator peut aussi fonctionner avec des affectations dstructures:

let [winner, ...losers] = poniesInRace;


// assuming 'poniesInRace' is an array containing several ponies
// 'winner' will have the first pony,
// and 'losers' will be an array of the other ones

Le rest operator ne doit pas tre confondu avec le spread operator ("oprateur dtalement"), mme si,
on te laccorde, ils se ressemblent dangeureusement! Le spread operator est son oppos: il prend un
tableau, et ltale en arguments variables. Le seul cas dutilisation qui me vient lesprit serait pour les
fonctions comme min ou max, qui peuvent recevoir des arguments variables, et que tu voudrais appeler
avec un tableau:

let ponyPrices = [12, 3, 4];


let minPrice = Math.min(...ponyPrices);

3.8. Classes
Une des fonctionnalits les plus emblmatiques, et qui va largement tre utilise dans lcriture
dapplications Angular: ES6 introduit les classes en JavaScript! Tu pourras dsormais facilement faire
de lhritage de classes en JavaScript. Tu pouvais dj, avec lhritage prototypal, mais ce ntait pas
chose facile, surtout pour les dbutants

Maintenant cest les doigts dans le nez, regarde:

class Pony {
constructor(color) {
this.color = color;
}
toString() {
return `${this.color} pony`;
// see that? It is another cool feature of ES6, called template literals
// we'll talk about these quickly!
}
}
let bluePony = new Pony('blue');
console.log(bluePony.toString()); // blue pony

Les dclarations de classes, contrairement aux dclarations de fonctions, ne sont pas hoisted
("remontes"), donc tu dois dclarer une classe avant de lutiliser. Tu as probablement remarqu la
fonction spciale constructor. Cest le constructeur, la fonction appele la cration dun nouvel objet

12
avec le mot-cl new. Dans lexemple, il requiert une couleur, et nous crons une nouvelle instance de la
classe Pony avec la couleur "blue". Une classe peut aussi avoir des mthodes, appelables sur une
instance, comme la mthode toString() dans lexemple.

Une classe peut aussi avoir des attributs et des mthodes statiques:

class Pony {
static defaultSpeed() {
return 10;
}
}

Ces mthodes statiques ne peuvent tre appeles que sur la classe directement:

let speed = Pony.defaultSpeed();

Une classe peut avoir des accesseurs (getters, setters), si tu veux implmenter du code sur ces
oprations:

class Pony {
get color() {
console.log('get color');
return this._color;
}
set color(newColor) {
console.log(`set color ${newColor}`);
this._color = newColor;
}
}
let pony = new Pony();
pony.color = 'red'; // set color red
console.log(pony.color); // get color

Et bien videmment, si tu as des classes, lhritage est possible en ES6.

13
class Animal {
speed() {
return 10;
}
}
class Pony extends Animal {

}
let pony = new Pony();
console.log(pony.speed()); // 10, as Pony inherits the parent method

Animal est appele la classe de base, et Pony la classe drive. Comme tu las vu, la classe drive
possde toutes les mthodes de la classe de base. Mais elle peut aussi les redfinir:

class Animal {
speed() {
return 10;
}
}
class Pony extends Animal {
speed() {
return super.speed() + 10;
}
}
let pony = new Pony();
console.log(pony.speed()); // 20, as Pony overrides the parent method

Comme tu le vois, le mot-cl super permet dinvoquer la mthode de la classe de base, avec
super.speed() par exemple.

Ce mot-cl super peut aussi re utilis dans les constructeurs, pour invoquer le constructeur de la
classe de base:

14
class Animal {
constructor(speed) {
this.speed = speed;
}
}
class Pony extends Animal {
constructor(speed, color) {
super(speed);
this.color = color;
}
}
let pony = new Pony(20, 'blue');
console.log(pony.speed); // 20

3.9. Promises
Les promises ("promesses") ne sont pas si nouvelles, et tu les connais ou les utilises peut-tre dj,
parce quelles tenaient une place importante dans AngularJS1.x. Mais comme nous les utiliserons
beaucoup avec Angular2, et mme si tu nutilises que du pur JS sans Angular, on pense que cest
important de sy attarder un peu.

Lobjectif des promises est de simplifier la programmation asynchrone. Notre code JS est plein
dasynchronisme, comme des requtes AJAX, et en gnral on utilise des callbacks pour grer le
rsultat et lerreur. Mais le code devient vite confus, avec des callbacks dans des callbacks, qui le
rendent illisible et peu maintenable. Les promises sont plus pratiques que les callbacks, parce quelles
permettent dcrire du code plat, et le rendent ainsi plus simple comprendre. Prenons un cas
dutilisation simple, o on doit rcuprer un utilisateur, puis ses droits, puis mettre jour un menu
quand on a rcupr tout a.

Avec des callbacks:

getUser(login, function(user) {
getRights(user, function(rights) {
updateMenu(rights);
});
});

Avec des promises:

15
getUser()
.then(function(user) {
return getRights(user);
})
.then(function(rights) {
updateMenu(rights);
})

Jaime cette version, parce quelle sexcute comme elle se lit: je veux rcuprer un utilisateur, puis ses
droits, puis mettre jour le menu.

Une promise est un objet thenable, ce qui signifie simplement quil a une mthode then. Cette mthode
prend deux arguments: un callback de succs et un callback derreur. Une promise a trois tats:

pending ("en cours"): quand la promise nest pas ralise, par exemple quand lappel serveur nest
pas encore termin.

fulfilled ("ralise"): quand la promise sest ralise avec succs, par exemple quand lappel HTTP
serveur a retourn un status 200-OK.

rejected ("rejete"): quand la promise a chou, par exemple si lappel HTTP serveur a retourn un
status 404-NotFound.

Quand la promesse est ralise (fulfilled), alors le callback de succs est invoqu, avec le rsultat en
argument. Si la promesse est rejete (rejected), alors le callback derreur est invoqu, avec la valeur
rejete ou une erreur en argument.

Alors, comment cre-t-on une promise? Cest simple, il y a une nouvelle classe Promise, dont le
constructeur attend une fonction avec deux paramtres, resolve et reject.

let getUser = function() {


return new Promise(function(resolve, reject) {
// async stuff, like fetching users from server, returning a response
if (response.status === 200) {
resolve(response.data);
} else {
reject('No user');
}
});
};

Une fois la promise cre, tu peux enregistrer des callbacks, via la mthode then. Cette mthode peut
recevoir deux arguments, les deux callbacks que tu veux voir invoqus en cas de succs ou en cas
dchec. Dans lexemple suivant, nous passons simplement un seul callback de succs, ignorant ainsi
une erreur potentielle:

16
getUser()
.then(function(user) {
console.log(user);
})

Quand la promesse sera ralise, le callback de succs (qui se contente ici de tracer lutilisateur en
console) sera invoqu.

La partie la plus cool cest que le code peut scrire plat. Si par exemple ton callback de succs
retourne lui aussi une promise, tu peux crire:

getUser()
.then(function(user) {
return getRights(user) // getRights is returning a promise
.then(function(rights) {
return updateMenu(rights);
});
})

ou plus lgamment:

getUser()
.then(function(user) {
return getRights(user); // getRights is returning a promise
})
.then(function(rights) {
return updateMenu(rights);
})

Un autre truc cool est la gestion derreur: tu peux dfinir une gestion derreur par promise, ou globale
toute la chane.

Une gestion derreur par promise:

17
getUser()
.then(function(user) {
return getRights(user);
}, function(error) {
console.log(error); // will be called if getUser fails
return Promise.reject(error);
})
.then(function(rights) {
return updateMenu(rights);
}, function(error) {
console.log(error); // will be called if getRights fails
return Promise.reject(error);
})

Une gestion derreur globale pour toute la chane:

getUser()
.then(function(user) {
return getRights(user);
})
.then(function(rights) {
return updateMenu(rights);
})
.catch(function(error) {
console.log(error); // will be called if getUser or getRights fails
})

Tu devrais srieusement tntresser aux promises, parce que a va devenir la nouvelle faon dcrire
des APIs, et toutes les bibliothques vont bientt les utiliser. Mme les bibliothques standards: cest le
cas de la nouvelle Fetch API par exemple.

3.10. (arrow functions)


Un truc que jadore dans ES6 est la nouvelle syntaxe arrow function ("fonction flche"), utilisant
loprateur fat arrow ("grosse flche"): . Cest super utile pour les callbacks et les fonctions
anonymes!

Prenons notre exemple prcdent avec des promises:

18
getUser()
.then(function(user) {
return getRights(user); // getRights is returning a promise
})
.then(function(rights) {
return updateMenu(rights);
})

Il peut tre rcrit avec des arrow functions comme ceci:

getUser()
.then(user => getRights(user))
.then(rights => updateMenu(rights))

Nest-ce pas super cool?!

Note que le return est implicite sil ny a pas de bloc: pas besoin dcrire user return
getRights(user). Mais si nous avions un bloc, nous aurions besoin dun return explicite:

getUser()
.then(user => {
console.log(user);
return getRights(user);
})
.then(rights => updateMenu(rights))

Et les arrow functions ont une particularit bien agrable que nont pas les fonctions normales: le this
reste attach lexicalement, ce qui signifie que ces arrow functions nont pas un nouveau this comme
les fonctions normales. Prenons un exemple o on itre sur un tableau avec la fonction map pour y
trouver le maximum.

En ES5:

19
var maxFinder = {
max: 0,
find: function(numbers) {
// let's iterate
numbers.forEach(
function(element) {
// if the element is greater, set it as the max
if (element > this.max) {
this.max = element;
}
});
}
};

maxFinder.find([2, 3, 4]);
// log the result
console.log(maxFinder.max);

Ca semble pas mal, non? Mais en fait a ne marche pas Si tu as de bons yeux, tu as remarqu que le
forEach dans la fonction find utilise this, mais ce this nest li aucun objet. Donc this.max nest en fait
pas le max de lobjet maxFinder On pourrait corriger a facilement avec un alias:

var maxFinder = {
max: 0,
find: function(numbers) {
var self = this;
numbers.forEach(
function(element) {
if (element > self.max) {
self.max = element;
}
});
}
};

maxFinder.find([2, 3, 4]);
// log the result
console.log(maxFinder.max);

ou en bindant le this:

20
var maxFinder = {
max: 0,
find: function(numbers) {
numbers.forEach(
function(element) {
if (element > this.max) {
this.max = element;
}
}.bind(this));
}
};

maxFinder.find([2, 3, 4]);
// log the result
console.log(maxFinder.max);

ou en le passant en second paramtre de la fonction forEach (ce qui est justement sa raison dtre):

var maxFinder = {
max: 0,
find: function(numbers) {
numbers.forEach(
function(element) {
if (element > this.max) {
this.max = element;
}
}, this);
}
};

maxFinder.find([2, 3, 4]);
// log the result
console.log(maxFinder.max);

Mais il y a maintenant une solution bien plus lgante avec les arrow functions:

21
let maxFinder = {
max: 0,
find: function(numbers) {
numbers.forEach(element => {
if (element > this.max) {
this.max = element;
}
});
}
};

maxFinder.find([2, 3, 4]);
// log the result
console.log(maxFinder.max);

Les arrow functions sont donc idales pour les fonctions anynomes en callback!

3.11. Set et Map


On va faire court: on a maintenant de vraies collections en ES6. Youpi \o/!

On utilisait jusque-l de simples objets JavaScript pour jouer le rle de map ("dictionnaire"), cest dire
un objet JS standard, dont les cls taient ncessairement des chanes de caractres. Mais nous
pouvons maintenant utiliser la nouvelle classe Map :

let cedric = { id: 1, name: 'Cedric' };


let users = new Map();
users.set(cedric.id, cedric); // adds a user
console.log(users.has(cedric.id)); // true
console.log(users.size); // 1
users.delete(cedric.id); // removes the user

On a aussi une classe Set ("ensemble"):

let cedric = { id: 1, name: 'Cedric' };


let users = new Set();
users.add(cedric); // adds a user
console.log(users.has(cedric)); // true
console.log(users.size); // 1
users.delete(cedric); // removes the user

Tu peux aussi itrer sur une collection, avec la nouvelle syntaxe for of:

22
for (let user of users) {
console.log(user.name);
}

Tu verras que cette syntaxe for of est celle choisie par lquipe Angular pour itrer sur une
collection dans un template.

3.12. Template de string


Construire des strings a toujours t pnible en JavaScript, o nous devions gnralement utiliser des
concatnations:

let fullname = 'Miss ' + firstname + ' ' + lastname;

Les templates de string sont une nouvelle fonctionnalit mineure mais bien pratique, o on doit
utiliser des accents graves (backticks `) au lieu des habituelles apostrophes (quote ') ou apostrophes
doubles (double-quotes "), fournissant un moteur de template basique avec support du multi-ligne:

let fullname = `Miss ${firstname} ${lastname}`;

Le support du multi-ligne est particulirement adapt lcriture de morceaux dHTML, comme nous
le feront dans nos composants Angular:

let template = `<div>


<h1>Hello</h1>
</div>`;

3.13. Modules
Il a toujours manqu en JavaScript une faon standard de ranger ses fonctions dans un espace de
nommage, et de charger dynamiquement du code. NodeJS a t un leader sur le sujet, avec un
cosystme trs riche de modules utilisant la convention CommonJS. Ct navigateur, il y a aussi lAPI
AMD (Asynchronous Module Definition), utilis par RequireJS. Mais aucun ntait un vrai standard, ce
qui nous conduit des dbats incessants sur la meilleure solution.

ES6 a pour objectif de crer une syntaxe avec le meilleur des deux mondes, sans se proccuper de
limplmentation utilise. Le comit Ecma TC39 (qui est responsable des volutions dES6 et auteur de
la spcification du langage) voulait une syntaxe simple (cest indniablement latout de CommonJS),
mais avec le support du chargement asynchrone (comme AMD), et avec quelques bonus comme la
possibilit danalyser statiquement le code par des outils et une gestion claire des dpendances

23
cycliques. Cette nouvelle syntaxe se charge de dclarer ce que tu exportes depuis tes modules, et ce que
tu importes dans dautres modules.

Cette gestion des modules est fondamentale dans Angular2, parce que tout y est dfini dans des
modules, quil faut importer ds quon veut les utiliser. Supposons quon veuille exposer une fonction
pour parier sur un poney donn dans une course, et une fonction pour lancer la course.

Dans races_service.js:

export function bet(race, pony) {


// ...
}
export function start(race) {
// ...
}

Comme tu le vois, cest plutt simple: le nouveau mot-cl export fait son travail et exporte les deux
fonctions.

Maintenant, supposons quun composant de notre application veuille appeler ces deux fonctions:

Dans races_service.js

import { bet, start } from 'races_service';

// later
bet(race, pony1);
start(race);

Cest ce quon appelle un named export ("export nomm"). Ici on importe les deux fonctions, et on doit
spcifier le nom du fichier contenant ces deux fonctions, ici 'races_service'. Evidemment, on peut
importer une seule des deux fonctions, avec un alias mme si besoin:

import { start as startRace } from 'races_service';

// later
startRace(race);

Et si tu veux importer toutes les fonctions du module, tu peux utiliser le caractre joker *.

Comme tu le ferais dans dautres langages, il faut utiliser le caractre joker * avec modration,

24
seulement si tu as besoin de toutes les fonctions, ou la plupart. Et comme tout ceci sera prochainement
gr par ton IDE prfr qui prendra en charge la gestion automatique des imports, on naura plus se
soucier dimporter les seules bonnes fonctions.

Avec un caractre joker, tu dois utiliser un alias, et jaime plutt a, parce que a rend le reste du code
plus lisible:

import * as racesService from 'races_service';

// later
racesService.bet(race, pony1);
racesService.start(race);

Si ton module nexpose quune seule fonction, ou valeur, ou classe, tu nas pas besoin dutiliser un
named export, et tu peux bnficier de lexport par dfaut, avec le mot-cl default. Cest pratique pour
les classes notamment:

// pony.js
export default class Pony { }
// races_service.js
import Pony from 'pony';

Note labsence daccolade pour importer un export par dfaut. Tu peux limporter avec lalias que tu
veux, mais pour tre cohrent, cest mieux de limporter avec le nom du module (sauf videmment si
tu importes plusieurs modules portant le mme nom, auquel cas tu devras donner un alias pour les
distinguer). Et bien sr tu peux mlanger lexport par dfaut et lexport nomm, mais un module ne
pourra avoir quun seul export par dfaut.

En Angular2, tu utiliseras beaucoup de ces imports dans ton application. Chaque composant et service
sera une classe, gnralement isole dans son propre fichier et exporte, et ensuite importe la
demande dans chaque autre composant.

3.14. Conclusion
Voil qui conclue notre rapide introduction ES6. On a zapp quelques parties, mais si tu as bien
assimil ce chapitre, tu nauras aucun problme coder ton application en ES6. Si tu veux approfondir,
je te recommande chaudement Exploring JS par Axel Rauschmayer, ou Understanding ES6 par
Nicholas C. Zakas. Ces deux ebooks peuvent tre lus gratuitement en ligne, mais pense soutenir ces
auteurs qui ont fait un beau travail! En loccurrence, jai relu rcemment Speaking JS, le prcdent
livre dAxel, et jai encore appris quelques trucs, donc si tu veux raffraichir tes connaissances en JS, je
te le conseille vivement!

25
Chapter 4. Un peu plus loin quES6
4.1. Types dynamiques, statiques et optionnels
Tu sais probablement que les applications Angular2 peuvent tre crites en ES5, ES6, ou TypeScript. Et
tu te demandes peut-tre quest-ce que TypeScript, et ce quil apporte de plus.

JavaScript est dynamiquement typ. Tu peux donc faire des trucs comme:

let pony = 'Rainbow Dash';


pony = 2;

Et a fonctionne. a offre pleins de possibilits: tu peux ainsi passer nimporte quel objet une
fonction, tant que cet objet a les proprits requises par la fonction:

let pony = { name: 'Rainbow Dash', color: 'blue' };


let horse = { speed: 40, color: 'black' };
let printColor = animal => console.log(animal.color);
// works as long as the object has a `color` property

Cette nature dynamique est formidable, mais elle est aussi un handicap dans certains cas, compare
dautres langages plus fortement typs. Le cas le plus vident est quand tu dois appeler une fonction
inconnue dune autre API en JS: tu dois lire la documentation (ou pire le code de la fonction) pour
deviner quoi doivent ressembler les paramtres. Dans notre exemple prcdent, la mthode
printColor attend un paramtre avec une proprit color. a peut tre dur deviner, et cest encore
plus difficile dans notre travail quotidien, o on multiplie les utilisations de bibliothques et services
dvelopps par dautres. Un des co-fondateurs de Ninja Squad se plaint souvent du manque de type en
JS, et dclare quil nest pas aussi productif, et quil ne produit pas du code aussi bon quil le ferait dans
un environnement plus statiquement typ. Et il na pas entirement tort, mme sil trolle aussi par
plaisir! Sans les informations de type, les IDEs nont aucun indice pour savoir si tu cris quelque chose
de faux, et les outils ne peuvent pas taider trouver des bugs dans ton code. Bien sr, nos applications
sont testes, et Angular a toujours facilit les tests, mais cest pratiquement impossible davoir une
parfaite couverture de tests.

Cela nous ammne sur le sujet de la maintenabilit. Le code JS peut tre difficile maintenir, malgr
les tests et la documentation. Refactorer une grosse application JS nest pas chose aise,
comparativement ce qui peut tre fait dans des langages statiquement typs. La maintenabilit est un
sujet important, et les types aident les outils comme les dveloppeurs viter les erreurs lors de
lcriture et la modification de code. Google a toujours t enclin proposer des solutions dans cette
direction: cest comprhensible, tant donn quils grent des applications parmi les plus grosses du
monde, avec GMail, Google apps, Maps Alors ils ont essay plusieurs approches pour amliorer la
maintenablit des applications front-end: GWT, Google Closure, Dart Elles devaient toutes faciliter

26
lcriture de grosses applications web.

Avec Angular2, lquipe Google voulait nous aider crire du meilleur JS, en ajoutant des
informations de type notre code. Ce nest pas concept nouveau pour JS, ctait mme le sujet de la
spcification ECMASCRIPT4, qui a t abandonne. Au dpart ils annoncrent AtScript, un sur-
ensemble dES6 avec des annotations (des annotations de type et dautres, dont je parlerai plus tard).
Ils annoncrent ensuite le support de TypeScript, le langage de Microsoft, avec des annotations de type
additionnelles. Et enfin, quelques mois plus tard, lquipe TypeScript annonait, aprs un travail troit
avec lquipe de Google, que la nouvelle version du langage (1.5) aurait toutes les nouvelles
fonctionnalits dAtScript. Lquipe Angular dclara alors quAtScript tait officiellement abandonn,
et que TypeScript tait dsormais la meilleure faon dcrire des applications Angular2!

4.2. Hello TypeScript


Je pense que ctait la meilleure chose faire pour plusieurs raisons. Dabord, personne na vraiment
envie dapprendre une nouvelle extension de langage. Et TypeScript existait dj, avec une
communaut et un cosystme actifs. Je ne lavais jamais vraiment utilis avant Angular2, mais jen
avais entendu du bien, de personnes diffrentes. TypeScript est un projet de Microsoft, mais ce nest
pas le Microsoft de lre Balmer et Gates. Cest le Microsoft de Nadella, celui qui souvre la
communaut, et donc, lopen-source. Google en a conscience, et cest tout leur avantage de
contribuer un projet existant, plutt que de maintenir le leur. Le framework TypeScript gagnera de
son ct en visibilit: win-win comme dirait ton manager.

Mais la raison principale de parier sur TypeScript est le systme de types quil offre. Cest un systme
optionnel qui vient taider sans tentraver. De fait, aprs avoir cod quelque temps avec, il sest fait
compltement oublier: tu peux faire des applications Angular2 en utilisant les trucs de TypeScript les
plus utiles (jy reviendrai) et en ignorant tout le reste avec du pur JavaScript (ES6 dans mon cas). Mais
jaime ce quils ont fait, et on jettera un coup doeil TypeScript dans le chapitre suivant. Tu pourras
ainsi lire et comprendre nimporte quel code Angular2, et tu pourras dcider de lutiliser, ou pas, ou
juste un peu, dans tes applications.

Si tu te demandes "mais pourquoi avoir du code fortement typ dans une application Angular2?",
prenons un exemple. Angular 1 et 2 ont t construits sur le puissant concept dinjection de
dpendance. Tu le connais dj peut-tre, parce que cest un design pattern classique, utilis dans
beaucoup de frameworks et langages, et notamment AngularJS1.x comme je le disais.

4.3. Un exemple concret dinjection de dpendance


Pour synthtiser ce quest linjection de dpendence, prenons un composant dune application, disons
RaceList, permettant daccder la liste des courses que le service RaceService peut retourner. Tu peux
crire RaceList comme a:

27
class RaceList {
constructor() {
this.raceService = new RaceService();
// let's say that list() returns a promise
this.raceService.list()
// we store the races returned into a member of `RaceList`
.then(races => this.races = races);
// arrow functions, FTW!
}
}

Mais ce code a plusieurs dfauts. Lun deux est la testabilit: cest compliqu de remplacer raceService
par un faux service (un bouchon, un mock), pour tester notre composant.

Si nous utilisons le pattern dinjection de dpendance (Dependency Injection, DI), nous dlguons la
cration de RaceService un framework, lui rclamant simplement une instance. Le framework est
ainsi en charge de la cration de la dpendance, et il peut nous "linjecter", par exemple dans le
constructeur:

class RaceList {
constructor(raceService) {
this.raceService = raceService;
this.raceService.list()
.then(races => this.races = races);
}
}

Dsormais, quand on teste cette classe, on peut facilement passer un faux service au constructeur:

// in a test
let fakeService = {
list: () => {
// returns a fake list
}
};
let raceList = new RaceList(fakeService);
// now we are sure that the race list
// is the one we want for the test

Mais comment le framework sait-il quel composant injecter dans le constructeur? Bonne question!
AngularJS1.x se basait sur le nom du paramtre, mais cela a une srieuse limitation: la minification
du code va changer le nom du paramtre. Pour contourner ce problme, tu pouvais utiliser la notation
base de tableau, ou ajouter des mtadonnes la classe:

28
RaceList.inject = ['RaceService'];

Il nous fallait donc ajouter des mtadonnes pour que le framework comprenne ce quil fallait injecter
dans nos classes. Et cest exactement ce que proposent les annotations de type: une mtadonne
donnant un indice ncessaire au framework pour raliser la bonne injection. En Angular2, avec
TypeScript, voil quoi pourrait ressembler notre composant RaceList:

class RaceList {
raceService: RaceService;
races: Array<string>;

constructor(raceService: RaceService) {
// the interesting part is `: RaceService`
this.raceService = raceService;
this.raceService.list()
.then(races => this.races = races);
}
}

Maintenant linjection peut se faire sans ambiguit! Tu nes pas oblig dutiliser TypeScript en
Angular2, mais clairement ton code sera plus lgant avec. Tu peux toujours faire la mme chose en
pur ES6 ou ES5, mais tu devras ajouter manuellement des mtadonnes dune autre faon (on y
reviendra en dtail).

Cest pourquoi nous allons passer un peu de temps apprendre TypeScript (TS). Angular2 est
clairement construit pour tirer parti dES6 et TS 1.5+, et rendre notre vie de dveloppeur plus facile en
lutilisant. Et lquipe Angular a envie de soumettre le systme de type au comit de standardisation,
donc peut-tre quun jour il sera normal davoir de vrais types en JS.

Il est temps dsormais de se lancer dans TypeScript!

29
Chapter 5. Dcouvrir TypeScript
TypeScript, qui existe depuis 2012, est un sur-ensemble de JavaScript, ajoutant quelques trucs ES5. Le
plus important tant le systme de type, lui donnant mme son nom. Depuis la version 1.5, sortie en
2015, cette bibliothque essaie dtre un sur-ensemble dES6, incluant toutes les fonctionnalits vues
prcdemment, et quelques nouveauts, comme les dcorateurs. Ecrire du TypeScript ressemble
crire du JavaScript. Par convention les fichiers sources TypeScript ont lextension .ts, et seront
compils en JavaScript standard, en gnral lors du build, avec le compilateur TypeScript. Le code
gnr reste trs lisible.

npm install -g typescript


tsc test.ts

Mais commenons par le dbut.

5.1. Les types de TypeScript


La syntaxe pour ajouter des informations de type en TypeScript est basique:

let variable: type;

Les diffrents types sont simples retenir:

let poneyNumber: number = 0;


let poneyName: string = 'Rainbow Dash';

Dans ces cas, les types sont facultatifs, car le compilateur TS peut les deviner depuis leur valeur (cest
ce quon appelle linfrence de type).

Le type peut aussi tre dfini dans ton application, avec par exemple la classe suivante Pony:

let pony: Pony = new Pony();

TypeScript supporte aussi ce que certains langages appellent des types gnriques, par exemple avec
un Array:

let ponies: Array<Pony> = [new Pony()];

Cet Array ne peut contenir que des poneys, ce quindique la notation gnrique <>. On peut se

30
demander quel est lintrt dimposer cela. Ajouter de telles informations de type aidera le compilateur
dtecter des erreurs:

ponies.push('hello'); // error TS2345


// Argument of type 'string' is not assignable to parameter of type 'Pony'.

Et comment faire si tu as besoin dune variable pouvant recevoir plusieurs types? TS a un type spcial
pour cela, nomm any.

let changing: any = 2;


changing = true; // no problem

Cest pratique si tu ne connais pas le type dune valeur, soit parce quelle vient dun bout de code
dynamique, ou en sortie dune bibliothque obscure.

Si ta variable ne doit recevoir que des valeurs de type number ou boolean, tu peux utiliser lunion de
types:

let changing: number|boolean = 2;


changing = true; // no problem

5.2. Valeurs numres (enum)


TypeScript propose aussi des valeurs numres: enum. Par exemple, une course de poneys dans ton
application peut tre soit ready, started ou done.

enum RaceStatus {Ready, Started, Done}


let race: Race = new Race();
race.status = RaceStatus.Ready;

Un enum est en fait une valeur numrique, commenant 0. Tu peux cependant dfinir la valeur que tu
veux:

enum Medal {Gold = 1, Silver, Bronze}

5.3. Return types


Tu peux aussi spcifier le type de retour dune fonction:

31
function startRace(race: Race): Race {
race.status = RaceStatus.Started;
return race;
}

Si la fonction ne retourne rien, tu peux le dclarer avec void:

function startRace(race: Race): void {


race.status = RaceStatus.Started;
}

5.4. Interfaces
Cest dj une bonne premire tape. Mais comme je le disais plus tt, JavaScript est formidable par sa
nature dynamique. Une fonction marchera si elle reoit un objet possdant la bonne proprit:

function addPointsToScore(player, points) {


player.score += points;
}

Cette fonction peut tre applique nimporte quel objet ayant une proprit score. Maintenant
comment traduit-on cela en TypeScript? Facile!, on dfinit une interface, un peu comme la "forme" de
lobjet.

function addPointsToScore(player: { score: number; }, points: number): void {


player.score += points;
}

Cela signifie que le paramtre doit avoir une proprit nomme score de type number. Tu peux
videment aussi nommer ces interfaces:

interface HasScore {
score: number;
}
function addPointsToScore(player: HasScore, points: number): void {
player.score += points;
}

32
5.5. Paramtre optionnel
Ya un autre truc sympa en JavaScript: les paramtres optionnels. Si tu ne les passes pas lappel de la
fonction, leur valeur sera undefined. Mais en TypeScript, si tu dclares une fonction avec des
paramtres typs, le compilateur te gueulera dessus si tu les oublies:

addPointsToScore(player); // error TS2346


// Supplied parameters do not match any signature of call target.

Pour montrer quun paramtre est optionnel dans une fonction (ou une proprit dans une interface),
tu ajoutes ? aprs le paramtre. Ici, le paramtre points est optionnel:

function addPointsToScore(player: HasScore, points?: number): void {


points = points || 0;
player.score += points;
}

5.6. Des fonctions en proprit


Tu peux aussi dcrire un paramtre comme devant possder une fonction spcifique plutt quune
proprit:

function startRunning(pony) {
pony.run(10);
}

La dfinition de cette interface serait:

interface CanRun {
run(meters: number): void;
}
function startRunning(pony: CanRun): void {
pony.run(10);
}

let pony = {
run: (meters) => logger.log(`pony runs ${meters}m`)
};
startRunning(pony);

33
5.7. Classes
Une classe peut implmenter une interface. Pour nous, un poney peut courir, donc on pourrait crire:

class Pony implements CanRun {


run(meters) {
logger.log(`pony runs ${meters}m`);
}
}

Le compilateur nous obligera implmenter la mthode run dans la classe. Si nous limplmentons
mal, par exemple en attendant une string au lieu dun number, le compilateur va crier:

class IllegalPony implements CanRun {


run(meters: string) {
console.log(`pony runs ${meters}m`);
}
}
// error TS2420: Class 'IllegalPony' incorrectly implements interface 'CanRun'.
// Types of property 'run' are incompatible.

Tu peux aussi implmenter plusieurs interfaces si a te fait plaisir:

class HungryPony implements CanRun, CanEat {


run(meters) {
logger.log(`pony runs ${meters}m`);
}
eat() {
logger.log(`pony eats`);
}
}

Et une interface peut en tendre une ou plusieurs autres:

interface Animal extends CanRun, CanEat {}

class Pony implements Animal {


// ...
}

Une classe en TypeScript peut avoir des proprits et des mthodes. Avoir des proprits dans une
classe nest pas une fonctionnalit standard dES6, cest seulement possible en TypeScript.

34
class SpeedyPony {
speed: number = 10;
run() {
logger.log(`pony runs at ${this.speed}m/s`);
}
}

Tout est public par dfaut. Mais tu peux utiliser le mot-cl private pour cacher une proprit ou une
mthode. Ajouter public ou private un paramtre de constructeur est un raccourci pour crer et
initialiser un membre priv ou public:

class NamedPony {
constructor(public name: string,
private speed: number) {}

run() {
logger.log(`pony runs at ${this.speed}m/s`);
}
}
let pony = new NamedPony('Rainbow Dash', 10);
// defines a public property name with 'Rainbow Dash'
// and a private one speed with 10

Ces raccourcis sont trs pratiques et nous allons beaucoup les utiliser en Angular2!

5.8. Utiliser dautres bibliothques


Mais si on travaille avec des bibliothques externes crites en JS, comment savoir les types des
paramtres attendus par telle fonction de telle bibliothque? La communaut TypeScript est tellement
cool que ses membres ont dfini des interfaces pour les types et les fonctions exposs par les
bibliothques JavaScript les plus populaires.

Les fichiers contenant ces interfaces ont une extension spciale: .d.ts. Ils contiennent une liste de
toutes les fonctions publiques des bibliothques. DefinitelyTyped est loutil de rfrence pour
rcuprer ces fichiers. Par exemple, si tu veux utiliser TS dans ton application AngularJS1.x, tu peux
rcuprer le fichier ddi depuis le repository:

tsd query angular --action install --save

Puis tu inclues ce fichier au dbut de ton code et hop!, tu profites du bonheur davoir une compilation
typesafe:

35
/// <reference path="angular.d.ts" />
angular.module(10, []); // the module name should be a string
// so when I compile, I get:
// Argument of type 'number' is not assignable to parameter of type 'string'.

/// <reference path="angular.d.ts" /> est un commentaire spcial reconnu par TS, qui indique au
compilateur de vrifier linterface angular.d.ts. Maintenant, si tu te trompes dans lappel dune
mthode AngularJS, le compilateur te le dira, et tu peux corriger sans avoir lancer manuellement ton
application!

Encore plus cool, depuis TypeScript 1.6, le compilateur est capable de trouver par lui-mme ces
interfaces si elles sont packages avec ta dpendance dans ton rpertoire node_modules. De plus en plus
de projets adoptent cette approche, et Angular2 fait de mme. Tu nas donc mme pas toccuper
dinclure ces interfaces dans ton projet Angular2: le compilateur TS va tout comprendre comme un
grand si tu utilises NPM pour grer tes dpendances!

5.9. Decorateurs
Cest une fonctionnalit toute nouvelle, ajoute seulement en TypeScript 1.5, juste pour le support
dAngular. En effet, comme on le verra bientt, les composants Angular2 peuvent tre dcrits avec des
dcorateurs. Tu nas peut-tre jamais entendu parler de dcorateurs, car tous les langages ne les
proposent pas. Un dcorateur est une faon de faire de la mta-programmation. Ils ressemblent
beaucoup aux annotations, qui sont principalement utilises en Java, C#, et Python, et peut-tre
dautres langages que je ne connais pas. Suivant le langage, tu peux ajouter une annotation sur une
mthode, un attribut, ou une classe. Gnralement, les annotations ne sont pas vraiment utiles au
langage lui-mme, mais plutt aux frameworks et aux bibliothques.

Les dcorateurs sont vraiment puissants: ils peuvent modifier leur cible (classes, mthodes, etc) et
par exemple modifier les paramtres ou le rsultat retourn, appeler dautres mthodes quand la cible
est appele, ou ajouter des mtadonnes destin un framework un bout de code (cest ce que font
les dcorateurs dAngular2). Jusqu prsent, cela nexistait pas en JavaScript. Mais le langage volue,
et il y a maintenant une proposition officielle pour le support des dcorateurs, qui les rendra peut-tre
possibles un jour (possiblement avec ES7/ES2016).

En Angular2, on utilisera les annotations fournies par le framework. Leur rle est assez simple: ils
ajoutent des mtadonnes nos classes, proprits ou paramtres pour par exemple indiquer "cette
classe est un composant", "cette dpendance est optionnelle", "ceci est une proprit spciale du
composant", etc Ce nest pas obligatoire de les utiliser, car tu peux toujours ajouter les mtadonnes
manuellement si tu ne veux que du pur ES5, mais le code sera plus lgant avec des dcorateurs,
comme ceux proposs par TypeScript.

En TypeScript, les annotations sont prfixes par @, et peuvent tre appliques sur une classe, une
proprit de classe, une fonction, ou un paramtre de fonction. Pas sur un constructeur en revanche,
mais sur ses paramtres oui.

36
Pour mieux comprendre ces dcorateurs, essayons den construire un trs simple par nous-mmes,
@Log(), qui va crire le nom de la mthode chaque fois quelle sera appele.

Il sutilisera comme a:

class RaceService {

@Log()
getRaces() {
// call API
}

@Log()
getRace(raceId) {
// call API
}
}

Pour le dfinir, nous devons crire une mthode renvoyant une fonction comme celle-ci:

let Log = function () {


return (target: any, name: string, descriptor: any) => {
logger.log(`call to ${name}`);
return descriptor;
};
};

Selon ce sur quoi nous voulons appliquer notre dcorateur, la fonction naura pas exactement les
mmes arguments. Ici nous avons un dcorateur de mthode, qui prend 3 paramtres:

target: la mthode cible par notre dcorateur

name: le nom de la mthode cible

descriptor: le descripteur de la mthode cible, par exemple est-ce que la mthode est numrable,
etc

Nous voulons simplement crire le nom de la mthode, mais tu pourrais faire pratiquement ce que tu
veux: modifier les paramtres, le rsultat, appeler une autre fonction, etc

Ici, dans notre exemple basique, chaque fois que les mthodes getRace() ou getRaces() sont executes,
nous verrons une nouvelle trace dans la console du navigateur:

37
raceService.getRaces();
// logs: call to getRaces
raceService.getRace(1);
// logs: call to getRace

En tant quutilisateur dAngular2, jetons un il ces annotations:

@Component({selector: 'home'})
class Home {

constructor(@Optional() hello: HelloService) {


logger.log(hello);
}

Lannotation @Component est ajoute la classe Home. Quand Angular2 chargera notre application, il va
trouver la classe Home, et va comprendre que cest un composant grce au dcorateur. Cool, hein?!
Comme tu le vois, une annotation peut recevoir des paramtres, ici un objet de configuration.

Je voulais juste prsenter le concept de dcorateur, nous aurons loccasion de revoir tous les
dcorateurs disponibles en Angular2 tout au long de ce livre.

Je dois aussi indiquer que tu peux utiliser les dcorateurs avec Babel comme transpileur la place de
TypeScript. Il y a mme un plugin pour supporter tous les dcorateurs Angular2: angular2-
annotations. Babel supporte aussi les proprits de classe, mais pas le systme de type apport par
TypeScript. Tu peux utiliser Babel, et crire du code "ES6+", mais tu ne pourras pas bnficier des
types, et ils sont sacrment utiles pour linjection de dpendances. Cest possible, mais tu devras
ajouter dautres dcorateurs pour remplacer les informations de type.

Ainsi mon conseil est dessayer TypeScript. Tous mes exemples dans ce livre lutiliseront. Il nest pas
intrusif, tu peux lutiliser quand cest utile et loublier le reste du temps. Si vraiment tu naimes pas, il
ne sera pas trs compliqu de repasser ES6 avec Babel ou Traceur, ou mme ES5 si tu es
compltement fou (mais pour ma part, je trouve le code ES5 dune application Angular2 vraiment pas
terrible!).

38
Chapter 6. Le monde merveilleux des Web
Components
Avant daller plus loin, jaimerais faire une petite pause pour parler des Web Components. Vous navez
pas besoin de connatre les Web Components pour crire du code Angular2. Mais je pense que cest
une bonne chose den avoir un aperu, car en Angular2 certaines dcisions ont t prises pour faciliter
leur intgration, ou pour rendre les composants que lon construit similaires des Web Components.
Tu es libre de sauter ce chapitre si tu ne tintresses pas du tout au sujet, mais je pense que tu
apprendras deux-trois choses qui pourraient ttre utiles pour la suite.

6.1. Le nouveau Monde


Les composants sont un vieux rve de dveloppeur. Un truc que tu prendrais sur tagre et lcherais
dans ton application, et qui marcherait directement et apporterait la fonctionnalit tes utilisateurs
sans rien faire.

Mes amis, cette heure est venue.

Oui, bon, peut-tre. En tout cas, on a le dbut dun truc.

Ce nest pas compltement neuf. On avait dj la notion de composants dans le dveloppement web
depuis quelques temps, mais ils demandaient en gnral de lourdes dpendances comme jQuery, Dojo,
Prototype, AngularJS, etc Pas vraiment le genre de bibliothques que tu veux absolument ajouter
ton application.

Les Web Components essaient de rsoudre ce problme: avoir des composants rutilisables et
encapsuls.

Ils reposent sur un ensemble de standards mergents, que les navigateurs ne supportent pas encore
parfaitement. Mais quand mme, cest un sujet intressant, mme si on ne pourra pas en bnficier
pleinement avant quelques annes, ou mme jamais sur le concept ne dcolle pas.

Ce standard mergent est dfini dans quatre spcifications:

Custom elements ("lments personnaliss")

Shadow DOM ("DOM de lombre")

Template

HTML imports

Note que les exemples prsents ont plus de chances de fonctionner dans un Chrome ou un Firefox
rcent.

39
6.2. Custom elements
Les lments customs sont un nouveau standard qui permet au dveloppeur de crer ses propres
lments du DOM, faisant de <pony-cmp><pony-cmp> un lment HTML parfaitement valide. La
spcification dfinit comment dclarer de tels lments, comment tu peux les faire tendre des
lments existants, comment tu peux dfinir ton API, etc

Dclarer un lment custom se fait avec un simple document.registerElement('pony-cmp'):

// new element
var PonyCmp = document.registerElement('pony-cmp');
// insert in current body
document.body.appendChild(new PonyCmp());

Note que le nom doit contenir un tiret, pour indiquer au navigateur que cest un lment custom.

videmment ton lment custom peut avoir des proprits et des mthodes, et il aura aussi des
callbacks lis au cycle de vie, pour excuter du code quand le composant est insr ou supprim, ou
quand lun de ses attributs est modifi. Il peut aussi avoir son propre template. Par exemple, peut-tre
que ce pony-cmp affiche une image du poney, ou seulement son nom:

// let's extend HTMLElement


var PonyCmpProto = Object.create(HTMLElement.prototype);
// and add some template using a lifecycle
PonyCmpProto.createdCallback = function() {
this.innerHTML = '<h1>General Soda</h1>';
};

// new element
var PonyCmp = document.registerElement('pony-cmp', {prototype: PonyCmpProto});
// insert in current body
document.body.appendChild(new PonyCmp());

Si tu jettes un coup dil au DOM, tu verras <pony-cmp><h1>General Soda</h1></pony-cmp>. Mais cela


veut dire que le CSS ou la logique JavaScript de ton application peut avoir des effets indsirables sur
ton composant. Donc, en gnral, le template est cach et encaspul dans un truc appel le Shadow
DOM ("DOM de lombre"), et tu ne verras dans le DOM que <pony-cmp><pony-cmp>, bien que le
navigateur affiche le nom du poney.

6.3. Shadow DOM


Avec un nom qui claque comme celui-l, on sattend un truc trs puissant. Et il lest. Le Shadow DOM
est une faon dencapsuler le DOM de ton composant. Cette encapsulation signifie que la feuille de style

40
et la logique JavaScript de ton application ne vont pas sappliquer sur le composant et le ruiner
accidentellement. Cela en fait loutil idal pour dissimuler le fonctionnement interne de ton
composant, et sassurer que rien nen fuit lextrieur.

Si on retourne notre exemple prcdent:

var PonyCmpProto = Object.create(HTMLElement.prototype);

// add some template in the Shadow DOM


PonyCmpProto.createdCallback = function() {
var shadow = this.createShadowRoot();
shadow.innerHTML = '<h1>General Soda</h1>';
};

var PonyCmp = document.registerElement('pony-cmp', {prototype: PonyCmpProto});


document.body.appendChild(new PonyCmp());

Si tu essaies maintenant de lobserver, tu devrais voir:

<pony-cmp>
#shadow-root (open)
<h1>General Soda</h1>
</pony-cmp>

Dsormais, mme si tu ajoutes du style aux lments h1, rien ne changera: le Shadow DOM agit comme
une barrire.

Jusqu prsent, nous avions utilis une chane de caractres pour notre template. Mais ce nest
habituellement pas la faon de procder. La bonne pratique est de plutt utiliser llment <template>.

6.4. Template
Un template spcifi dans un lment <template> nest pas affich par le navigateur. Son but est dtre
terme clon dans un autre lment. Ce que tu dclareras lintrieur sera inerte: les scripts ne
sexcuteront pas, les images ne se chargeront pas, etc Son contenu peut tre requt par le reste de
la page avec la mthode classique getElementById(), et il peut tre plac sans risque nimporte o dans
la page.

Pour utiliser un template, il doit tre clon:

41
<template id="pony-tpl">
<style>
h1 { color: orange; }
</style>
<h1>General Soda</h1>
</template>

var PonyCmpProto = Object.create(HTMLElement.prototype);

// add some template using the template tag


PonyCmpProto.createdCallback = function() {
var template = document.querySelector('#pony-tpl');
var clone = document.importNode(template.content, true);
this.createShadowRoot().appendChild(clone);
};

var PonyCmp = document.registerElement('pony-cmp', {prototype: PonyCmpProto});


document.body.appendChild(new PonyCmp());

Et si on pouvait dclarer cela dans un seul fichier, cela nous ferait un composant parfaitement
encapsul Cest ce que nous allons faire avec les imports HTML!

6.5. HTML imports


Cest la dernire spcification. Les imports HTML permettent dimporter du HTML dans du HTML.
Quelque chose comme <link rel="import" href="pony-cmp.html">. Ce fichier, pony-cmp.html,
contiendrait tout ce qui est requis: le template, les scripts, les styles, etc

Si quelquun voulait ensuite utiliser notre merveilleux composant, il lui suffirait simplement dutiliser
un import HTML.

6.6. Polymer et X-tag


Toutes ces spcifications constituent les Web Components. Je suis loin den tre expert, et ils prsentent
toute sorte de piges.

Comme les Web Components ne sont pas compltement supports par tous les navigateurs, il y a un
polyfill inclure dans ton application pour tre sr que a fonctionne. Ce polyfill est appel web-
component.js, et il est bon de noter quil est le fruit dun effort commun entre Google, Mozilla et
Microsoft, entre autres.

Au dessus de ce polyfill, quelques bibliothques ont vu le jour. Elles proposent toutes de faciliter le
travail avec les Web Components, et viennent souvent avec un lot de composants tout prts.

Parmi les initiatives notables, on peut citer:

42
Polymer de Google;

X-tag de Mozilla et Microsoft.

Je ne vais pas rentrer dans les dtails, mais tu peux facilement utiliser un composant Polymer existant.
Supposons que tu veuilles embarquer une carte Google dans ton application:

<!-- Polyfill Web Components support for older browsers -->


<script src="webcomponents.js"></script>

<!-- Import element -->


<link rel="import" href="google-map.html">

<!-- Use element -->


<body>
<google-map latitude="45.780" longitude="4.842"></google-map>
</body>

Il y a une tonne de composants disponibles. Tu peux en avoir un aperu sur https://customelements.io/.

Polymer permet aussi de crer tes propres composants:

<dom-module id="pony-cmp">
<template>
<h1>[[name]]</h1>
</template>
<script>
Polymer({
is: 'pony-cmp',
properties: {
name: String
}
});
</script>
</dom-module>

et de les utiliser:

43
<!-- Polyfill Web Components support for older browsers -->
<script src="webcomponents.js"></script>

<!-- Polymer -->


<link rel="import" href="polymer.html">

<!-- Import element -->


<link rel="import" href="pony-cmp.html">

<!-- Use element -->


<body>
<pony-cmp name="General Soda"></pony-cmp>
</body>

Tu peux faire plein de trucs cools avec Polymer, comme du binding bi-directionnel, donner des valeurs
par dfaut aux attributs, mettre des vnements custom, ragir aux modifications dattribut, rpter
des lments si tu fournis une collection un composant, etc

Cest un chapitre trop court pour te montrer srieusement tout ce que lon peut faire avec les Web
Components, mais tu verras que certains de leurs concepts vont merger dans la lecture venir. Et tu
verras sans aucun doute que lquipe Google a conu Angular2 pour rendre facile lutilisation des Web
Components aux cts de nos composants Angular2.

44
Chapter 7. La philosophie dAngular2
Pour construire une application Angular2, il te faut saisir quelques trucs sur la philosophie du
framework.

Avant tout, Angular2 est un framework orient composant. Tu vas crire de petits composants, et
assembls, ils vont constituer une application complte. Un composant est un groupe dlments
HTML, dans un template, ddis une tche particulire. Pour cela, tu auras probablement besoin
dun peu de logique mtier derrire ce template, pour peupler les donnes, et ragir aux vnements
par exemple. Pour les vtrans dAngularJS1.x, cest un peu comme le fameux duo "template/
controlleur", ou une directive.

Il faut aussi dire quun standard a t dfini autour de ces composants: le standard Web Component
("composant web"). Mme sil nest pas encore compltement support dans les navigateurs, tu peux
dj construire des petits composants isols, rutilisables dans diffrentes applications (ce vieux rve
de programmeur). Cette orientation composant est largement partage par de nombreux frameworks
front-end: cest le cas depuis le dbut de ReactJS, le framework tendance de Facebook; EmberJS et
AngularJS ont leur propre faon de faire quelque chose de similaire; et les petits nouveaux Aurelia ou
Vue.js parient aussi sur la construction de petits composants.

45
Angular2 nest donc pas le seul sur le sujet, mais ils sont parmi les premiers (ou le premier?)
considrer srieusement lintgration des Web Components (ceux du standard officiel). Mais cartons
ce sujet, trop avanc pour le moment.

Tes composants seront organiss de faon hirarchique, comme le DOM: un composant racine aura
des composants enfants, qui auront chacun des composants enfants, etc Si tu veux afficher une
course de poneys (qui ne voudrait pas?), tu auras probablement une application (Poneyracer), avec
une vue enfant (Race), affichant un menu (Menu), lutilisateur connect (User), et, videmment, les
poneys (Pony) en course:

Comme tu vas crire des composants tous les jours (de la semaine au moins), regardons de plus prs
quoi a ressemble. Lquipe Angular voulait aussi bnficier dune autre ppite du dveloppement web
moderne: ES6 (ou ES2015, si tu prfres). Ainsi tu peux crire tes composants en ES5 (pas cool!) ou en
ES6 (super cool!). Mais cela ne leur suffisait pas, ils voulaient utiliser une fonctionnalit qui nest pas

46
encore standard: les dcorateurs. Alors ils ont travaill troitement avec les quipes de transpileurs
(Traceur et Babel) et lquipe Microsoft du projet TypeScript, pour nous permettre dutiliser des
dcorateurs dans nos applications Angular2. Quelques dcorateurs sont disponibles, permettant de
dclarer facilement un composant et sa vue. Jespre que tu es au courant, parce que je viens de
consacrer deux chapitres ces sujets!

Par exemple, en simplifiant, le composant Race pourrait ressembler a:

import {Component} from 'angular2/core';


import {Pony} from './components';
import {RacesService} from './services';

@Component({
selector: 'race',
templateUrl: 'race/race.html',
directives: [Pony]
})
export class RaceCmp {

race: any;

constructor(racesService: RacesService) {
racesService.get()
.then(race => this.race = race);
}
}

Et le template pourrait ressembler a:

<div>
<h2>{{ race.name }}</h2>
<div>{{ race.status }}</div>
<div *ngFor="#pony of race.ponies">
<pony [pony]="pony"></pony>
</div>
</div>

Si tu connais dj AngularJS1.x, le template doit ttre familier, avec les mme expressions entre
accolades {{ }}, qui seront values et remplaces par les valeurs correspondantes. Certains trucs ont
cependant chang: plus de ng-repeat par exemple. Je ne veux pas aller trop loin pour le moment, juste
te donner un aperu du code.

Un composant est une partie compltement isole de ton application. Ton application est un composant
comme les autres. Dans un monde idal, tu prendrais nimporte quel composant fourni par la
communaut et en bnficierais dans ton application, en lajoutant quelque part dans la hirarchie.

47
Dans les chapitres suivants, on explorera quoi mettre en place, comment construire un petit
composant, et la syntaxe des templates.

Il y a un autre concept au cur dAngular2: linjection de dpendance (Dependency Injection, DI). Cest
un pattern trs puissant, et tu seras trs rapidement sduit aprs la lecture du chapitre qui lui sera
consacr. Cest particulirement utile pour tester ton application, et jadore faire des tests, et voir la
barre de progression devenir entirement verte dans mon IDE. a me donne limpression de faire du
bon boulot. Il y aura ainsi un chapitre entier consacr tout tester: tes composants, tes services, ton
interface

Angular a toujours cette sensation magique de la v1, o les modifications sont automatiquement
dtectes par le framework et appliques au modle et la vue. Mais cest fait dune faon trs
diffrente: la dtection de changement utilise dsormais un concept nomm zones. On tudiera
videmment tout a.

Angular est aussi un framework complet, avec plein doutils pour faciliter les tches classiques du
dveloppement web. Construire des formulaires, appeler un serveur HTTP, du routage dURL, interagir
avec dautres bibliothques, des animations, tout ce que tu veux: cest possible!

Voil, a fait pas mal de trucs apprendre! Alors commenons par le commencement: initialiser une
application et construire notre premier composant.

48
Chapter 8. Commencer de zro
8.1. Crer une application avec TypeScript
Commenons par crer notre premire application Angular2 et notre premier composant, avec un
minimum doutillage. Tu devras installer Node.js et NPM sur ton systme. Comme la meilleure faon de
le faire dpend de ton systme dexploitation, le mieux est daller voir le site officiel. Assure-toi davoir
une version suffisamment rcente de Node.js (en excutant node --version), quelque-chose comme
4.2+. On va crire notre application en TypeScript, donc tu devras linstaller aussi, via npm:

npm install -g typescript

Ensuite, tu vas crer un nouveau rpertoire pour notre exprimentation, et utiliser tsc depuis ce
nouveau rpertoire vide pour y initialiser un projet. tsc sont les initiales de TypeScript Compiler
("compilateur TypeScript"). Il est fourni par le module NPM typescript quon vient dinstaller
globalement:

tsc --init --target es5 --sourceMap --experimentalDecorators --emitDecoratorMetadata

Cela va crer un fichier, tsconfig.json, qui stockera les options de compilation TypeScript. Comme on
la vu dans les chapitres prcdents, on va utiliser TypeScript avec des dcorateurs (do les deux
derniers flags), et on veut que notre code soit transpil en ECMASCRIPT5, lui permettant dtre excut
par tout navigateur. Loption sourceMap permet de gnrer les source maps ("dictionnaires de code
source"), cest--dire des fichiers assurant le lien entre le code ES5 gnr et le code TypeScript originel.

Ces source maps sont utiliss par le navigateur pour te permettre de dbugger le code ES5 quil excute
en parcourant le code TypeScript originel que tu as crit.

On va maintenant utiliser notre IDE prfr. Tu peux utiliser peu prs ce que tu veux, mais tu devrais
y activer le support de TypeScript pour plus de confort (et tassurer quil supporte TypeScript 1.5+)
Choisis ton IDE prfr: Webstorm, Atom, VisualStudio Code Ils ont tous un bon support de
TypeScript.

Le compilateur TypeScript (et aussi souvent lIDE) sappuie sur le fichier tsconfig.json pour savoir
quelles options il doit utiliser. Le fichier devrait ressembler celui-ci:

49
{
"compilerOptions": {
"target": "es5",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"sourceMap": true,
"module": "commonjs",
"noImplicitAny": false,
"outDir": "built",
"rootDir": "."
},
"exclude": [
"node_modules"
]
}

Tu peux voir que quelques options ont t ajoutes par dfaut. Une intressante est loption module, qui
indique que notre code va tre packag sous forme de modules CommonJS. Cela deviendra important
dans un moment.

Maintenant on est prt lancer le compilateur TypeScript, en utilisant le watch mode ("mode de
surveillance") pour compiler en tche de fond ds la sauvegarde. Il se peut aussi que ton IDE puisse
sen charger.

tsc --watch

Cela devrait afficher quelque chose comme:

Compilation complete. Watching for file changes.

Tu peux dsormais laisser ce compilateur tourner en fond et ouvrir une nouvelle ligne de commande
pour la suite.

On doit maintenant ajouter la bibliothque Angular2 et notre code. Pour la bibliothque Angular2, on
va la tlcharger avec NPM, un chouette outil pour grer ses dpendances.

Pour viter quelques problmes, nous allons utiliser NPM version 2. Vrifie quelle version tu as avec:

npm -v

Si tu as NPM version 3, tu peux facilement installer NPM version 2:

50
npm install -g npm@2

Maintenant que cest fait, commenons par crer le fichier package.json, qui contient toutes les
informations dont NPM a besoin. Tu peux rpondre par Entre toutes les questions.

npm init

Ensuite, installons angular2 et ses dpendances:

npm install --save angular2

Tu peux jeter un coup dil au fichier package.json, il devrait dsormais contenir les dpendances
suivantes:

reflect-metadata, parce que nous utilisons les dcorateurs.

es6-shim et es6-promise sont incluses, pour tre sr que le navigateur aura tout ce dont il a besoin.

rxjs, une bibliothque vraiment cool appele RxJS pour la programmation ractive. On aura un
chapitre entier consacr ce sujet.

et enfin, le module zone.js, qui assure la plomberie pour faire tourner notre code dans des zones
isoles et y dtecter les changements (on y reviendra aussi plus tard).

Loutillage est dsormais en place, il est temps de crer notre premier composant!

8.2. Notre premier composant


Cre un nouveau fichier, nomm ponyracer_app.ts.

Ds que tu sauveras ce fichier, tu devrais voir apparatre un nouveau fichier ponyracer_app.js dans le
rpertoire built: cest le compilateur TypeScript qui fait son travail. Sinon, cest que tu as
probablement arrt ton compilateur TypeScript qui surveillait les changements, alors tu devrais le
lancer nouveau avec tsc --watch, et le laisser tourner en fond.

Comme on la vu dans le chapitre prcdent, un composant est la combinaison dune vue (le template)
et de logique (notre classe TS). Crons une classe:

export class PonyRacerApp {

Notre application elle-mme est un simple composant. Pour indiquer Angular que cen est un, on

51
utilise le dcorateur @Component. Pour pouvoir lutiliser, il nous faut limporter:

import {Component} from 'angular2/core';

@Component()
export class PonyRacerApp {

Si ton IDE le supporte, la compltion de code devrait fonctionner car la dpendance Angular2 a ses
propres fichiers d.ts dans le rpertoire node_modules, et TypeScript est capable de le dtecter. Tu peux
mme naviguer vers les dfinitions de type si tu le souhaites.

TypeScript apporte sa vrification de types, donc tu verras les erreurs ds que tu les tapes. Mais les
erreurs ne sont pas ncessairement bloquantes: si tu as oubli dajouter les informations de type sur
ta variable, le code compilera quand mme en JavaScript et sexcutera correctement.

Jessaie de mon ct de garder le compte des erreurs TypeScript zro, mais tu peux faire comme tu
veux. Comme nous utilisons des source maps, tu peux voir le code TypeScript directement dans ton
navigateur, et mme dbugger ton application en positionnant des points darrt directement dedans.

Le dcorateur @Component attend un objet de configuration. On verra plus tard en dtails ce quon peut
y configurer, mais pour le moment une seule proprit est requise: selector. Elle indiquera Angular
ce quil faudra chercher dans nos pages HTML. A chaque fois que le slecteur dfini sera trouv dans
notre HTML, Angular remplacera llment slectionn par notre composant:

import {Component} from 'angular2/core';

@Component({
selector: 'ponyracer-app'
})
export class PonyRacerApp {

Donc ici, chaque fois que notre HTML contiendra un lment <ponyracer-app></ponyracer-app>,
Angular crera une nouvelle instance de notre classe PonyRacerApp.

Un composant doit aussi avoir un template. On pourrait externaliser le template dans un autre fichier,
mais contentons-nous de faire simple la premire fois, et mettons le en ligne:

52
import {Component} from 'angular2/core';

@Component({
selector: 'ponyracer-app',
template: '<h1>PonyRacer</h1>'
})
export class PonyRacerApp {

Noublie pas dimporter le dcorateur Component si tu veux lutiliser. Tu loublieras rgulirement au


dbut, mais tu ty feras vite, parce que le compilateur ne va cesser de tinsulter! ;)

Tu verras que lessentiel de nos besoins se situe dans le module angular2/core, mais ce nest pas
toujours le cas. Par exemple, quand on fera du HTTP, on utilisera des imports de angular2/http, ou
quand on utilisera le routeur, on importera depuis angular2/router, etc

8.3. Dmarrer lapplication


Enfin, on doit dmarrer lapplication. Pour cela, il y a une mthode bootstrap notre disposition. Il
nous faut aussi limporter, depuis angular2/platform/browser. Cest quoi ce module bizarre?! Pourquoi
nest-ce pas angular2/core? Bonne question: cest parce que tu pourrais avoir envie de faire tourner
ton application ailleurs que dans un navigateur, parce quAngular2 permet le rendu ct serveur, ou
peut tourner dans un Web Worker par exemple. Et dans ces cas, la logique de dmarrage sera un peu
diffrente. Mais on verra cela plus tard, on va se contenter dun navigateur pour le moment.

Crons un nouveau fichier, par exemple bootstrap.ts, pour sparer la logique de dmarrage:

import {bootstrap} from 'angular2/platform/browser';


import {PonyRacerApp} from './ponyracer_app';

bootstrap(PonyRacerApp)
.catch(err => console.log(err)); // useful to catch the errors

Youpi! Mais attends voir. On na pas encore de fichier HTML, si? Tas raison!

Cre un autre fichier nomm index.html et ajoutes-y le contenu suivant:

53
<html>

<head></head>

<body>
<ponyracer-app>
You will see me while Angular starts the app!
</ponyracer-app>
</body>

</html>

Il nous faut maintenant ajouter nos scripts dans nos fichiers HTML. En AngularJS1.x, ctait simple: il
te suffisait dajouter un script pour angular.js, et un script pour chacun des fichiers JS que tu avais
crits, et ctait bon. Il y avait cependant un inconvnient: tout devait tre charg statiquement, ds le
dmarrage, ce qui pouvait allonger lourdement les temps de chargement pour les grosses applications.

Avec Angular2, cest plus complexe, mais aussi bien plus puissant. Angular est maintenant modulaire,
et chaque module peut tre charg dynamiquement. Notre application est donc aussi modulaire,
comme on la vu.

Il y a cependant quelques problmes:

la notion de module nexiste pas en ES5, et les navigateurs ne supportent que ES5 pour le moment;

les concepteurs dES6 ont dcid de spcifier comment les modules taient dfinis et imports. Mais
ils nont pas encore spcifi comment ils devaient tre packags et chargs par les navigateurs.

Pour charger nos modules, il nous faudra donc sappuyer sur un outil: SystemJS. SystemJS est un petit
chargeur de modules: tu lajoutes (statiquement) dans ta page HTML, tu lui indiques o sont situs les
modules sur le serveur, et tu charges lun deux. Il dterminera automatiquement les dpendances
entre les modules, et tlchargera ceux utiliss par ton application.

Cela va entraner des pellets de tlchargements de fichiers JS. Si cela nest pas un problme pendant
le dveloppement, a le devient en production. Heureusement, SystemJS vient aussi avec un outil qui
peut emballer plusieurs petits modules dans un plus gros paquet. Quand un module est requis, le
paquet contenant ce module (et plusieurs autres) sera alors tlcharg.

Installons SystemJS:

npm install --save systemjs

On doit charger SystemJS statiquement, et lui indiquer o se situe notre module contenant la logique de
dmarrage (dans built/bootstrap). On doit aussi lui montrer o trouver les dpendances de notre
application, comme angular2. Mais dabord, il nous faut inclure angular2-polyfills, un script spcial

54
qui doit tre charg en premier, pour inclure reflect-metadata et zone.js:

<html>

<head>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.js"></script>
<script>
System.config({
// we want to import modules without writing .js at the end
defaultJSExtensions: true,
// the app will need the following dependencies
map: {
'angular2': 'node_modules/angular2',
'rxjs': 'node_modules/rxjs'
}
});
// and to finish, let's boot the app!
System.import('built/bootstrap');
</script>
</head>

<body>
<ponyracer-app>
You will see me while Angular starts the app!
</ponyracer-app>
</body>

</html>

OK! Dmarrons maintenant un serveur HTTP pour servir notre mini application. Je vais utiliser http-
server, un outil Node.js qui fait ce que laisse deviner son nom. Mais tu peux videmment utiliser ton
serveur web prfr: Apache, Nginx, Tomcat, etc Pour linstaller, on utilisera npm:

npm install -g http-server

Pour le dmarrer, va dans ton rpertoire, et entre:

http-server

Maintenant cest la grande premire! Ouvre ton navigateur sur http://localhost:8080.

Tu devrais y voir brivement "You will see this while Angular start the app!", puis ensuite "PonyRacer"
devrait apparatre! Ton premier composant est un succs!

55
Bon, OK, pour le moment ce nest pas vraiment une application dynamique, on aurait pu faire la mme
chose en une seconde dans une page HTML statique. Alors jetons-nous sur les chapitres suivants, et
apprenons tout de linjection de dpendances et du systme de templates.

8.4. Commencer de zro avec angular-cli


Dans un vrai projet, il te faudra probablement mettre en place dautres choses comme:

des tests pour vrifier que tu nas pas introduit de rgressions;

un outil de construction, pour orchestrer diffrentes tches (compiler, tester, packager, etc)

Et cest un peu laborieux de tout mettre en place tout seul, mme si je pense que cest utile de le faire
au moins une fois pour comprendre tout ce qui se passe.

Ces dernires annes, plusieurs petits projets ont vu le jour, tous bass sur le formidable Yeoman.
Ctait dj le cas avec AngularJS1.x, et il y a dj plusieurs tentatives avec Angular2.

Mais cette fois-ci, lquipe Google a travaill sur le sujet, et ils en ont sorti ceci: angular-cli.

angular-cli est un outil en ligne de commande pour dmarrer rapidement un projet, dj configur
avec un outil de construction (Broccoli), des tests, du packaging, etc

Cette ide nest pas nouvelle, et est dailleurs pique dun autre framework populaire: EmberJS et son
ember-cli largement plbiscit.

Loutil est encore en dveloppement, mais je pense quil va devenir le standard de fait pour crer une
application Angular2 dans le futur, alors tu peux lessayer:

npm i -g angular-cli
ng new ponyracer

Cela va crer un squelette de projet. Tu peux dmarrer lapplication avec:

ng serve

Cela va dmarrer un petit serveur HTTP localement, avec rechargement chaud. Ainsi, chaque
modification de fichier, lapplication sera rafrachie dans le navigateur.

Tu peux aussi crer un squelette de composant:

ng component pony

Cela va crer un fichier de composant, avec son template associ, sa feuille de style, et un fichier de

56
test.

Loutil nest pas seulement l pour nous aider dvelopper notre application: il vient avec un systme
de plugins qui vont faciliter dautres tches comme le dploiement. Par exemple, tu peux rapidement
dployer sur Github Pages, avec le plugin github-pages:

ng github-pages:deploy

terme, cela devrait tre formidable! On partagera la mme organisation du code travers les
projets, une faon commune de construire et dployer les applications, et probablement un large
cosystme de plugins pour simplifier certaines tches.

Alors nhsite pas jeter un il angular-cli!

57
Chapter 9. Fin de lextrait gratuit
Voil, jespre que ce que tu as lu taura combl, et que tu rves dsormais de lire la suite! :)

58

Vous aimerez peut-être aussi