BEGINNER WORKSHOP TO ANGULARJS
WHO AM I?
ARI LERNER, FULLSTACK.IO
Author of ng-book and ng-newsletter
Author of a few others (D3 on Angular, Riding Rails with
AngularJS)
Teacher at HackReactor, General Assembly
Co-founder of Fullstack.io
Background in distributed computing and infrastructure
NG-BOOK.COM
TOOLS
TEXT EDITOR
Sublime Text 2/3
Textmate
Vim
Emacs
WEB BROWSER
Chrome
Firefox
Safari
WEB SERVER
Python
$pto - SmlHTSre 80
yhn m ipeTPevr 00
#o
r
$tit -owb-pt .
wsd n e -ah
WEB SERVER
NodeJS
$nmisalht-evrp ntl tpsre g
$ht-evr. - 80
tpsre / p 00
WEB SERVER
Golang
pcaemi
akg an
ipr (
mot
"m" "o" "e/tp
ft; lg; ntht"
)
fn mi( {
uc an)
ftPitn"evn tecretdrcoyo pr 88"
m.rnl(Srig h urn ietr n ot 00)
ht.ade"" ht.ieevrht.i(.))
tpHnl(/, tpFlSre(tpDr"")
er: ht.itnnSre"88" nl
r = tpLseAdev(:00, i)
i er! nl{
f r = i
lgFtl"itnnSre " er
o.aa(LseAdev: , r)
}
}
WEB SERVER
Serve the current directory
FLICKR API KEY
BUILDING OUR FIRST APP
Enter a name here

HELLO, !
DEMO
<tln-p>
hm gap
<ed
ha>
<il>et/il>
tteTs<tte
<ha>
/ed
<oy
bd>
<nu tp=tx"n-oe=yuNm"paeodr"ne anm hr"
ipt ye"et gmdl"orae lchle=Etr
ae ee>
<3Hlo{ yuNm }!/3
h>el { orae }<h>
<cit
srp
sc"tp:/jxgolai.o/jxlb/nuaj/..2aglrmnj"
r=hts/aa.ogepscmaa/isaglrs121/nua.i.s>
<srp>
/cit
<bd>
/oy
<hm>
/tl
n-p
gap
n-oe=yuNm"
gmdl"orae
{ yuNm }
{ orae }
DEFINE AN APPLICATION
DEFINE A MODULE
/ Ste
/ etr
aglrmdl(mAp,[)
nua.oue'yp' ];
/ Gte
/ etr
aglrmdl(mAp)
nua.oue'yp'
INVOKING OUR APPLICATION
ng-app
INVOKING OUR APPLICATION
<tl
hm>
<ed
ha>
<cit
srp
sc"tp:/jxgolai.o/jxlb/nuaj/..2aglrmnj"
r=hts/aa.ogepscmaa/isaglrs121/nua.i.s>
<srp>
/cit
<ha>
/ed
<oyn-p=mAp>
bd gap"yp"
<- Apiainrn fo hr ->
!- plcto us rm ee <bd>
/oy
<hm>
/tl
INVOKING OUR APPLICATION
<tl
hm>
<ed
ha>
<cit
srp
sc"tp:/jxgolai.o/jxlb/nuaj/..2aglrmnj"
r=hts/aa.ogepscmaa/isaglrs121/nua.i.s>
<srp>
/cit
<ha>
/ed
<oyn-p=mAp>
bd gap"yp"
<- Apiainrn fo hr ->
!- plcto us rm ee <bd>
/oy
<hm>
/tl

bd.gp(mAp)
oynAp'yp';
DIRECTIVE?!??
DIRECTIVES ARE FUNCTIONS
fnto symg {
ucin a(s)
aet"i"+mg;
lr(H
s)
}
...RUN ON ELEMENTS
fnto symg {
ucin a(s)
aet"i"+mg;
lr(H
s)
}

<i sy"ol"<dv
dv a=wrd>/i>

Say
BUILT-IN DIRECTIVES
NG-CLICK
<4Saei { sae}<h>
h>tt s { tt }/4
<utnn-lc=sae=!tt"Cag sae/utn
bto gcik"tt
sae>hne tt<bto>

STATE IS

Change state
NG-SHOW/NG-HIDE
<utnn-lc=sae=!tt"Cag sae/utn
bto gcik"tt
sae>hne tt<bto>
<i n-hw"tt"
dv gso=sae>
<4Imoto hdn we tesaei tu<h>
h>' u f iig hn h tt s re/4
<4Wee<h>
h>eee/4
<dv
/i>
<i n-ie"tt"
dv ghd=sae>
<4BO<h>
h>O!/4
<4Imol soigwe tesaei nttu<h>
h>' ny hwn hn h tt s o re/4
<dv
/i>

Change state
BOO!
I'M ONLY SHOWING WHEN THE STATE IF NOT TRUE
NG-MODEL
<nu n-oe=nm"tp=tx"paeodr"ne yu nm"/
ipt gmdl"ae ye"et lchle=Etr or ae >
<4{ nm }<h>
h>{ ae }/4

Enter your name
NG-REPEAT
<ln-nt"ae='r' 'nn' '' 'ob'"
u gii=nms[Ai, Aad, Q, Cly]>
<in-eet"aei nms>{nm }<l>
l grpa=nm n ae"{ ae }/i
<u>
/l

Ari
Anand
Q
Colby
EXPRESSIONS
Angular expressions are similar to JavaScript and can be thought
of like it.
<i> +2={ 1+2}<dv
dv1
{
}/i>
< n-lc=cut=cut+1>d oet tecut/>
a gcik"on
on
"Ad n o h on<a
EXPRESSIONS

ng.
thi
ood can be thought
Angular expressions are similar to JavaScript and
ag
of like it.ich is
h
,w
ors
<i> +2={ 1+2}<dv
dv1
{
}/i>
err t t e c u t / >
< n-lc=cut=cut+1>d oe o h on<a
a gcik"on
on
"Ad n
row
h
't t
on
d
ey
Th
SCOPES
Expressions have access to the variables inside the parent scope
DOING STUFF
AND WHAT ABOUT THE JAVASCRIPT?
SCOPES
The $ c p object is the glue between our JavaScript and our
soe
view (HTML).
<2Wloebc { ue.ae}<h>
h>ecm ak { srnm }/2
SCOPES

ed?
The $ c p object is the glue between fin JavaScript and our
soe
de our
e
m
view (HTML).
a
n
.
r
e
s
< 2 W l o e b c { u e . a e } <u
h>ecm ak { srnm }/2
h>
e is
her
W
$SCOPE
$cp.sr={
soeue
nm:'r'
ae Ai
}
;
SCOPES ARE JUST POJOS
/ Cet vrals
/ rae aibe
$cp.esg ='el'
soemsae
Hlo;
/ o ojcs
/ r bet
$cp.sr={
soeue
nm:'r'
ae Ai
}
;
/ Dfn fntos
/ eie ucin
$cp.a =fnto(s){
soesy
ucinmg
aet$cp.esg +""+mg;
lr(soemsae
s)
}
$
?
Just a name...
e?
nam
a

$
s in ?
at'

Wh a name...
Just
VIEW
<2{ msae}<h>
h>{ esg }/2
<3Wloebc { ue.ae}<h>
h>ecm ak { srnm }/3
<uto n-lc=sy"ol"'Syhlo/uto>
bttn gcik'a(Wrd)>a el<bttn

HELLO

WELCOME BACK ARI
Say hello
HOW TO GET ACCESS TO THE $ C P
SOE
CONTROLLERS
A controller is a piece of code that defines functionality for a part
of the page. Controllers are like mediators of functionality for
portions of the page.
<i n-otolr"dCnrle"
dv gcnrle=Adotolr>
<3Cuti a:{ cut}<h>
h>on s t { on }/3
< n-lc=adn("Adoe/>
a gcik"dOe)>d n<a
<dv
/i>
DEFINE A CONTROLLER
aglrmdl(mAp,[)
nua.oue'yp' ]
.otolr'dCnrle' fnto(soe {
cnrle(Adotolr, ucin$cp)
/ W hv acs t teHmCnrle' $cp
/ e ae ces o h oeotolrs soe
$cp.on =0
soecut
;
$cp.dOe=fnto( {
soeadn
ucin)
$cp.on + 1
soecut = ;
}
};
)
DATA
Client-side applications are only as exciting as the data they
contain.
GETTING DATA
$ t p a wrapper on the browser's XMLHttpRequest API.
h t is
$tp{
ht(
mto:'E'
ehd GT,
ul 'tp/aifik.o/evcsrs'
r: ht:/p.lcrcmsrie/et,
prm:{
aas
/ Fik AIprmtr
/ lcr P aaees
mto:'lcritrsigesgtit,
ehd fik.neetnns.eLs'
aiky aie,
p_e: pKy
fra:'sn,
omt jo'
njoclbc:1
osnalak
}
};
)
XHR REQUESTS ARE ASYNC
CALLBACKS
$aa(
.jx{
ul:'xml.o'
r
eapecm,
tp:'E'
ye GT,
sces:fnto(aa {
ucs
ucindt)
/ Sces:!
/ ucs )
}
,
err fnto(esn {
ro: ucinrao)
/ Fiue:
/ alr (
}
}
)
CALLBACK HELL

f.edi(ore fnto(r,fls {
sradrsuc, uciner ie)
i (r){
f er
cnoelg'ro fnigfls '+er
osl.o(Err idn ie:
r)
}es {
le
flsfrahfnto(ieae flIdx {
ie.oEc(ucinflnm, iene)
cnoelgflnm)
osl.o(ieae
g(ore+flnm)sz(uciner vle){
msuc
ieae.iefnto(r, aus
i (r){
f er
cnoelg'ro ietfigfl sz:'+er
osl.o(Err dniyn ie ie
r)
}es {
le
cnoelgflnm +':'+vle)
osl.o(ieae
aus
apc =(auswdh/vle.egt
set
vle.it
aushih)
wdh.oEc(ucinwdh wdhne){
itsfrahfnto(it, itIdx
hih =Mt.on(it /apc)
egt
ahrudwdh
set
cnoelg'eiig'+flnm +'o'+hih +''+hih)
osl.o(rszn
ieae
t
egt
x
egt
ti.eiewdh hih)wiedsiain+''+wdh+''+flnm,f
hsrsz(it, egt.rt(etnto
w
it
_
ieae u
i (r)cnoelg'ro wiigfl:'+er
f er osl.o(Err rtn ie
r)
}
)
}bn(hs)
.idti)
}
}
)
}
)
}
};
)
PROMISES
Rather than passing a callback function into the $ t p
h t method
to get called when the data returns, the $ t p
h t object returns a
promise.
PROMISE API
poie
rms
.hnfnto(aa {
te(ucindt)
/ Cle we n err hv ocre wt dt
/ ald hn o ros ae curd ih aa
}
)
.ac(uciner {
cthfnto(r)
/ Cle we a errhsocre
/ ald hn n ro a curd
}
)
.ial(ucindt){
fnlyfnto(aa
/ Cle awy,rgrls o teotu rsl
/ ald las eades f h upt eut
}
)
USING $ T P
HT
aglrmdl(mAp,[)
nua.oue'yp' ]
.otolr'oeotolr,fnto(soe $tp {
cnrle(HmCnrle' ucin$cp, ht)
$cp.ePoo =fnto( {
soegthts
ucin)
$tp{
ht(
mto:'E'
ehd GT,
ul 'tp/aifik.o/evcsrs'
r: ht:/p.lcrcmsrie/et,
prm:{
aas
/ Fik AIprmtr
/ lcr P aaees
mto:'lcritrsigesgtit,
ehd fik.neetnns.eLs'
aiky aie,
p_e: pKy
fra:'sn,
omt jo'
prpg:3
e_ae ,
njoclbc:1
osnalak
}
}.hnfnto(aa {
)te(ucindt)
$cp.hts=dt.aapoo.ht;
soepoo
aadt.htspoo
};
)
}
};
)

Get photos
BUT WAIT A MINUTE
How come we can even call the $ t p
h t object?
aglrmdl(mAp,[)
nua.oue'yp' ]
.otolr'oeotolr,fnto(soe $tp {
cnrle(HmCnrle' ucin$cp, ht)
};
)
BUT WAIT A MINUTE
How come we can even call the $ t p
h t object?
!??!
aglrmdl(mAp,[)
nua.oue'yp' ]
c
ic?p , $ t p {
.otolr'oeotolr,fnto(soe ht)
cnrle(HmCnrle' ucin$
ag
M
};
)
DEPENDENCY INJECTION
Anytime we rely on a library (%99.9999999999 of all code we
write), it either:

needs to find the dependency itself or
needs to be handed the dependency
DEPENDENCY INJECTION
Angular handles this ugly process for us by making objects and
injecting them for us when invoking the objects.
aglrmdl(mAp,[)
nua.oue'yp' ]
.otolr'oeotolr,fnto(soe $tp {
cnrle(HmCnrle' ucin$cp, ht)
/ Bcuew'enmdte
/ eas ev ae hm
/ $cp ad$tp
/ soe n ht
/ aglrwl poieteet orcnrle
/ nua il rvd hs o u otolr
};
)
REMEMBER OUR M D L ?
OUE
/ te[ i als o mdl dpnece
/ h ] s
it f oue eednis
aglrmdl(mAp,[)
nua.oue'yp' ];
DEPENDENCY INJECTION
naming matters
order does not matter
on?
ati
ific
min

DEPENDENCY INJECTION
e
dl
namingnmatters
ha
to
order does not matter
w
Ho
p...
hel
can
hat
kt
naming o
bo matters
w a does not matter
order
kno
I

DEPENDENCY INJECTION
TEMPORARY $ C P OBJECTS
SOE
Controllers are temporary objects and hang around only while
they are needed.
SO HOW DO WE STORE DATA?
For instance, how do we keep a user logged in through the lifecycle of our application?
SERVICES
Singleton objects that persist for the life-cycle of the
application
A container for like methods and data
BUILT-IN SERVICES
Like directives, Angular comes packed with services and
providers (a special type of service)
$tp
ht
$ieu
tmot
$ c (security)
se
$o
lg
$
q
and more
CREATING OUR OWN SERVICE
aglrmdl(mAp)
nua.oue'yp'
.evc(Fik' fnto(ht){
srie'lcr, ucin$tp
ti.ePoo =fnto( {
hsgthts
ucin)
/ Dfn gthts)fnto
/ eie ePoo( ucin
}
};
)
CREATING OUR OWN SERVICE
aglrmdl(mAp)
nua.oue'yp'
.atr(Fik' fnto(ht){
fcoy'lcr, ucin$tp
rtr {
eun
gthts fnto( {
ePoo: ucin) }
}
};
)
CREATING OUR OWN SERVICE
aglrmdl(mAp)
nua.oue'yp'
.rvdr'lcr,fnto( {
poie(Fik' ucin)
vraie =';
a pKy
'
ti.eAie =fnto(e){
hsstpKy
ucinky
rtr aie =ky| aie;
eun pKy
e | pKy
}
ti.gt=fnto(ht){
hs$e
ucin$tp
ti.ePoo =fnto( {;
hsgthts
ucin) }
rtr ti;
eun hs
}
};
)
CREATING OUR OWN SERVICE
The p o i e ( is the only type of service we can use in the
rvdr)
c n i ( block as [ a e P o i e
ofg)
Nm]rvdr
aglrmdl(mAp)
nua.oue'yp'
.ofgfnto(lcrrvdr {
cni(ucinFikPoie)
FikPoie.eAie(KY)
lcrrvdrstpKy'E';
};
)
CONFIG()
The c n i ( function runs before our app is running and let's
ofg)
us set up the app.
RUN()
The r n )
u ( function is the first function to get run before any
other part of our app.
USING OUR SERVICE
Just like using Angulars!
aglrmdl(mAp)
nua.oue'yp'
.otolr'oeotolr,fnto(soe Fik){
cnrle(HmCnrle' ucin$cp, lcr
Fik.ePoo(
lcrgthts)
.hnfnto(aa {
te(ucindt)
$cp.hts=dt.hts
soepoo
aapoo;
};
)
};
)
NEVER USE THE $ T PIN A CONTROLLER
HT
WHY?
WHAT ABOUT MULTIPLE PAGES?
ROUTING
INSTALLATION
<tln-p>
hm gap
<ed<ha>
ha>/ed
<oy
bd>
<cit
srp
sc"tp:/jxgolai.o/jxlb/nuaj/..2aglrmnj"
r=hts/aa.ogepscmaa/isaglrs121/nua.i.s>
<srp>
/cit
<cit
srp
sc"tp:/jxgolai.o/jxlb/nuaj/..2aglrruemnj"
r=hts/aa.ogepscmaa/isaglrs121/nua-ot.i.s>
<srp>
/cit
<bd>
/oy
<hm>
/tl
INSTALLATION
/ Tl orAglrapo tenw
/ el u nua p f h e
/ nRuemdl dpnec
/ got oue eedny
aglrmdl(mAp,[nRue]
nua.oue'yp' 'got')
LAYOUTS
We can now define our routes, but where how will they show up
on the page?
LAYOUTS
We can now define our routes, but where how will they show up
on the page?
<oy
bd>
<edrHae<hae>
hae>edr/edr
<i n-iw">/i>
dv gve="<dv
<otrFoe<foe>
foe>otr/otr
<bd>
/oy
LAYOUTS
nRue
g o t switches the child element of the n V e directive.
giw
DEFINING ROUTES
The n R u e
g o t module provides us with a new provider where
we'll define routes called the $ o t P o i e .
ruervdr
aglrmdl(mAp)
nua.oue'yp'
.ofgfnto(ruervdr {
cni(ucin$otPoie)
/ Cniueorrue hr
/ ofgr u ots ee
};
)
DEFINING ROUTES: WHEN()
The w e ( method allows us to define a route and a route
hn)
configuration object.
aglrmdl(mAp)
nua.oue'yp'
.ofgfnto(ruervdr {
cni(ucin$otPoie)
$otPoie
ruervdr
.hn'' {
we(/,
tmltUl 'epae/oehm'
epaer: tmltshm.tl,
cnrle:'oeotolr
otolr HmCnrle'
}
)
};
)
DEFINING ROUTES: OTHERWISE()
The o h r i e )
t e w s ( method defines a catch-all route if no other
route matches:
aglrmdl(mAp)
nua.oue'yp'
.ofgfnto(ruervdr {
cni(ucin$otPoie)
$otPoie
ruervdr
.tews(
ohrie{
rdrcT:''
eieto /
}
)
};
)
TESTING
TESTING
Gives us assurance our code works as expected
Allows for confidence with application deployment
Knowledge transfer and maintainability
...
UNIT TESTING
Based off Jasmine syntax, Angular's Karma test runner runs our
tests in a headless browser in several different browsers, such as
Chrome, Safari, and PhantomJS.
UNIT TESTING
Focuses on testing small, atomic pieces of functionality.
dsrb(Ui cnrles ' fnto({
ecie'nt otolr: , ucin)
/ Mc temApmdl
/ ok h yp oue
bfrEc(oue'yp')
eoeahmdl(mAp);
dsrb(HmCnrle' fnto( {
ecie'oeotolr, ucin)
/ Lclvrals
/ oa aibe
vrHmCnrle,soe
a oeotolr cp;
bfrEc(net
eoeahijc(
fnto(cnrle,$otcp){
ucin$otolr roSoe
/ Cet anwcidsoe
/ rae
e hl cp
soe=$otcp.nw)
cp
roSoe$e(;
HmCnrle =$otolr'oeotolr,{
oeotolr
cnrle(HmCnrle'
$cp:soe
soe cp
};
)
})
);
i(sol hv nm st,fnto( {
t'hud ae ae e' ucin)
epc(cp.ae.oeeie(;
xetsoenm)tBDfnd)
};
)
};
)
};
)
UNIT TESTING
Do it.
ife.
l
ur
yo
ave
ill s
w
, it
y
usl Do it.
o
eri
S

UNIT TESTING
END-TO-END TESTING
Instead of clicking the browser trying to mimic our user's
actions...
E2E TESTING
Karma's test runner
tor
c
tra
Pro
Karma's test runner

E2E TESTING
PROTRACTOR
Protractor is an end-to-end test framework built off the
WebDriverJS browser automation framework.
END-TO-END TESTING OUR PAGE
dsrb(pg la' fnto( {
ecie'ae od, ucin)
vrln;
a ik
bfrEc(ucin){
eoeahfnto(
ln =eeetb.s(.edru l:t-hl());
ik
lmn(ycs'hae l inhcid2')
ln.lc(;
ikcik)
};
)
i(sol nvgt t te/bu pg' fnto( {
t'hud aiae o h aot ae, ucin)
epc(rwe.eCretr()tMth//bu/;
xetbosrgturnUl).oac(aot)
};
)
};
)
THANK YOU
NG-BOOK.COM
630+ page book with all this information and much much more.
The only constantly updating book available for Angular today.
ADDENDUM (JUST IN CASE)
CONTROLLERS HANDLE BUSINESS LOGIC
<i n-otolr"dCnrle"
dv gcnrle=Adotolr>
<3Cuti a:{ cut}<h>
h>on s t { on }/3
< n-lc=adn("Adoe/>
a gcik"dOe)>d n<a
<dv
/i>

COUNT IS AT: 0
Add one

Beginner workshop to angularjs presentation at Google