Building a dynamic SPA
a journey with @filipbech
@IMPACTdigitaldk
Filip
@filipbech
!
#weAreHiring #denmark
https://www.facebook.com/groups/ngAarhus/
https://developers.google.com/experts/people/filip-bruun-bech-larsen
…enough about me
let’s use Angular for dynamic content
Building a dynamic SPA
a journey with @filipbech
@IMPACTdigitaldk
or “How to use Angular
with your cms”
Let’s do like angular 1
NOPE
need to bootstrap a component
…but we have no root app?
• multiple entrypoints
Bootstrapping multiple
applications
• its a little harder to maintain state between applications
(but possible)
• the cms now needs to know what components are
angular-components, so they can all be bootstrapped.
(and their DOM-nodes if multiple of the same
component)
Initial data
• We need to feed data (settings, initial data) into some of
the components (from the cms), and put content inside
them.
NOPE
Because
• Root-components cannot have inputs
• Root-components cannot use content-projection
(transclusion)
https://github.com/angular/angular/issues/1858
How about a <body>-
component then?
Eeeewwwww
• even though it works - it feels terrible and wrong!
• and we need the parser at runtime
• so no AOT and bad perf
We need a SPA
Single Page Application
• so we can also share state between routes
• animate route-changes
• and much more…
Demo-time
to heighten the suspense…
It starts with a router
…thats not very dynamic
We have too many routes with
no patterns
• “/“ is a frontpage
• “/om/os” is a content-page
• “/mejeri“ is a category-page
• “/mejeri/ost“ is a sub-category-page
• “/ost-i-skiver-mild-13-cheasy-200-g” is a product-page
So I talked to the Angular team…
…let the CMS
output route-config
Two issues with that approach
• Need to build and invalidate the bundle’s cache every
time an editor makes a change
• Users get stuck on the route-config they get at first load
One route to rule them all
**-route + generic
PageComponent
Get the data in a resolve
PageResolve is just a class with resolve(route)-method on it
In angular 1.x we could use templateFactory and
select a template based on the api-response
But we cannot do that in Angular 2+, because 

there is no template-parser at runtime
All possible
PageComponents with
individual *ngIf’s
Eeeewwwww
Even though all the *ngIfs in the template are AOT
compiled into something more acceptable…
It still seems wrong to have it in the template!
but (for now) it works…
until you navigate around

(nothing happens)
you’re not changing the route
just its options
(so: no new resolve, no new ngOnInit)
Refactoring
• Listen for route-changes and handle resolving data
manually
The problem cascades
• When we go from one product-detail-page to another
product-detail-page…
• Refactor init-logic into ngOnChanges
Then came rc4
ComponentFactoryResolver adds beauty
and power to generic components…
The theory
What components
should be available?
We need a routeChange
for animations
and it would feel a lot better too
Custom RouterReuseStrategy
What about Rich-text
content from the CMS?
ng-bind-html
Perfect, except for links
the router doesn’t “hijack”
a[href]-clicks like uiRouter
enter the [href] directive
NOPE
@Hostlistener =>
router.go()
* in reality it’s a little more complicated
Sweeeet
all we ever wanted
Without all the ugly
Flexibility
real routes => getting data in resolve + animations
Rich Text
Same approach for the
dynamic content spots
* we add another directive so we can repeat via *ngForOf
AOT
#justWorks
Add PageComponents to
ngModule entryComponents
Faster and lighter
Initial parse goes from 450ms to 250ms
Without AOT
With AOT
Server Side Rendering
SEO, social previews and 

faster perceived load-times
Angular Universal is so hot right now…(in core)
Hard to wrap your head
around universal
The idea
• server.module and a client.module
• they both import the app.module
• server and client module then replaces the
dependencies that are different with appropriate
environment-versions (eg. xhr or node-fetch, DOM or
virtual-dom)
Can’t touch this (the DOM)
(no direct window, querySelector, localstorage)
Maintaining state
we want to maintain state, so we don’t re-do all fetches
and calculations when the client boots up
StateTransfer Service
holds data
+ hooks for dehydrate/rehydrate via json
* idea credit to the universal creators…
CACHING OF SSR
can’t work with personalisation
3 strategies
at Launch
at user
interaction
just don’t
enter no-ssr directive
We made it to nirvana
Thank you, this was:
“building a dynamic SPA with Angular”
I’m @filipbech
code: https://github.com/filipbech/ng-dynamic-spa
@IMPACTdigitaldk
Building a dynamic SPA website with Angular

Building a dynamic SPA website with Angular