Components Are the New Thin Client

Lukas Ruebbelke
Lukas RuebbelkeOne Hungry Mind at VenturPlex LLC
components are the new
THIN CLIENT!
Story Time
DOM
jQuery “Application”
$( "form" ).submit(function( event ) {
if ( $( "input:first" ).val() === "correct" ) {
$( "span" ).text( "Validated..." ).show();
return;
}
$( "span" ).text( "Not valid!" ).show().fadeOut( 1000 );
event.preventDefault();
});
DOM
First Generation AngularJS Application
CONTROLLER
DOM
Second Generation AngularJS Application
CONTROLLER SERVICE
DOM CONTROLLER
Typical Stateful Service
Enter Redux
STOREREDUCERS
In classical physics, if you know everything about a
system at some instant of time, and you also know the
equations that govern how the system changes then you
can predict the future. That's what we mean when we say
that the classical laws of physics are deterministic. If we
can say the same thing, but with the past and future
reversed, the same equations tell you everything about
the past. Such a system is called reversible.
The Theoretical Minimum by Leonard Susskind
Components Are the New Thin Client
In classical physics, if you know everything about a
system at some instant of time, and you also know the
equations that govern how the system changes then you
can predict the future. That's what we mean when we say
that the classical laws of physics are deterministic. If we
can say the same thing, but with the past and future
reversed, the same equations tell you everything about
the past. Such a system is called reversible.
The Theoretical Minimum by Leonard Susskind
STORE!
In classical physics, if you know everything about a
system at some instant of time, and you also know the
equations that govern how the system changes then you
can predict the future. That's what we mean when we say
that the classical laws of physics are deterministic. If we
can say the same thing, but with the past and future
reversed, the same equations tell you everything about
the past. Such a system is called reversible.
The Theoretical Minimum by Leonard Susskind
REDUCERS!
In classical physics, if you know everything about a
system at some instant of time, and you also know the
equations that govern how the system changes then you
can predict the future. That's what we mean when we say
that the classical laws of physics are deterministic. If we
can say the same thing, but with the past and future
reversed, the same equations tell you everything about
the past. Such a system is called reversible.
The Theoretical Minimum by Leonard Susskind
In classical physics, if you know everything about a
system at some instant of time, and you also know the
equations that govern how the system changes then you
can predict the future. That's what we mean when we say
that the classical laws of physics are deterministic. If we
can say the same thing, but with the past and future
reversed, the same equations tell you everything about
the past. Such a system is called reversible.
The Theoretical Minimum by Leonard Susskind
User Input and Response
Components Are the New Thin Client
Components Are the New Thin Client
Time and Space
ACTIONS!
Components Are the New Thin Client
Components Are the New Thin Client
Components Are the New Thin Client
Components Are the New Thin Client
Space: Manual Dispatch
CLICK
DISPATCH
actions = [
{type: '[Client] Select', payload: {id: '1', firstName: 'John', lastName: 'Doe', company: 'Acme, Inc'}},
{type: '[Client] Select', payload: {id: '2', firstName: 'Jane', lastName: 'Smith', company: 'Super, Inc'}},
{type: '[Client] Select', payload: {id: '1', firstName: 'John', lastName: 'Doe', company: 'Acme, Inc'}},
{type: '[Client] Select', payload: {id: '2', firstName: 'Jane', lastName: 'Smith', company: 'Super, Inc'}},
{type: '[Client] Select', payload: {id: '1', firstName: 'John', lastName: 'Doe', company: 'Acme, Inc'}},
{type: '[Client] Select', payload: {id: '2', firstName: 'Jane', lastName: 'Smith', company: 'Super, Inc'}},
];
index = 0;
step() {
this.index = this.index < this.actions.length - 1 ? this.index + 1 : 0;
this.store.dispatch(this.actions[this.index]);
}
Manual Dispatch
DEMO TIME!
Time: Manual Cycle
CLICK
DISPATCH
actions = [
{type: '[Client] Select', payload: {id: '1', firstName: 'John', lastName: 'Doe', company: 'Acme, Inc'}},
{type: '[Client] Select', payload: {id: '2', firstName: 'Jane', lastName: 'Smith', company: 'Super, Inc'}},
{type: '[Client] Select', payload: {id: '1', firstName: 'John', lastName: 'Doe', company: 'Acme, Inc'}},
{type: '[Client] Select', payload: {id: '2', firstName: 'Jane', lastName: 'Smith', company: 'Super, Inc'}},
{type: '[Client] Select', payload: {id: '1', firstName: 'John', lastName: 'Doe', company: 'Acme, Inc'}},
{type: '[Client] Select', payload: {id: '2', firstName: 'Jane', lastName: 'Smith', company: 'Super, Inc'}},
];
cycle() {
const result = Observable
.from(this.actions)
.zip(Observable.interval(this.timerInterval), (a, b) => a)
;
result.subscribe(action => this.store.dispatch(action));
}
Manual Cycle
DEMO TIME!
Space: Dynamic Dispatch
SUBMIT
CLICK
DISPATCH
fetchSingle() {
this.actionsService
.single()
.subscribe(action => this.action = JSON.stringify(action, null , 't'));
}
dispatch(action) {
this.store.dispatch(JSON.parse(action));
}
Dynamic Dispatch
DEMO TIME!
Time: Dynamic Cycle
SUBMIT
CLICK
DISPATCH
fetchAll() {
this.actionsService
.all()
.subscribe(actions => this.rawActions = JSON.stringify(actions, null , 't'));
}
dispatchCycle(rawActions) {
const actions = JSON.parse(rawActions);
const result = Observable
.from(actions)
.zip(Observable.interval(this.timerInterval), (a, b) => a)
;
result.subscribe((action: any) => this.store.dispatch(action));
}
Dynamic Dispatch
DEMO TIME!
Space: Remote Dispatch
Components Are the New Thin Client
Components Are the New Thin Client
constructor(
private actionsService: ActionsService,
private store: Store<reducers.AppState>,
private afs: AngularFirestore
) {
this.remoteActions = afs.collection('actions');
}
ngOnInit() {
this.remoteActions.valueChanges()
.skip(1)
.subscribe((actions: any) => {
this.store.dispatch(actions[0]);
});
}
dispatchRemote(action) {
this.remoteActions.add(JSON.parse(action));
}
Remote Dispatch
DEMO TIME!
Time: Undo and Redo
export function undoable(reducer: ActionReducer<any>): ActionReducer<any> {
// Call the reducer with empty action to populate the initial state
const initialState = {
past: [],
present: reducer(undefined, { type: ''}),
future: []
};
// Return a reducer that handles undo and redo
return function (state = initialState, action) {
const { past, present, future } = state;
switch (action.type) {
case 'UNDO':
// UNDO LOGIC
case 'REDO':
// REDO LOGIC
default:
// REGULAR LOGIC
}
};
}
Meta Reducer
DEMO TIME!
Components Are the New Thin Client
REAL WORLD APPLICATIONS
Redux Airbrake
https://www.npmjs.com/package/redux-airbrake
@castillo__io
BONUS SLIDE!
Space and Time:
Thin Component
const CLIENT_LOAD = '[Client] Load';
const CLIENT_CREATE = '[Client] Create';
const CLIENT_UPDATE = '[Client] Update';
const CLIENT_DELETE = '[Client] Delete';
const CLIENT_SELECT = '[Client] Select';
const CLIENT_CLEAR = '[Client] Clear';
Actions
const reducer = (state = initialState, {type, payload}) => {
switch (type) {
case CLIENT_LOAD:
return state;
case CLIENT_SELECT:
return selectClient(state, payload);
case CLIENT_CREATE:
return createClient(state, payload);
case CLIENT_UPDATE:
return updateClient(state, payload);
case CLIENT_DELETE:
return deleteClient(state, payload);
case CLIENT_CLEAR:
return clearClient(state, payload);
default:
return state;
}
};
const store = new Store(reducer, initialState);
Reducer
export class ClientsComponent implements OnInit {
clients$: Observable<Client[]>;
currentClient$: Observable<Client>;
constructor(private store: Store) {
this.clients$ = this.store.select('clients');
this.currentClient$ = this.store.select('currentClient');
}
ngOnInit() {
this.store.dispatch(new ClientActions.LoadAction());
this.resetCurrentClient();
}
resetCurrentClient() {
const newClient: Client = { id: null, firstName: '', lastName: '', company: '' };
this.store.dispatch(new ClientActions.SelectAction(newClient));
}
}
ClientsComponent
class Store {
constructor(reducer) {
this.reducer = reducer;
this.state = reducer(undefined, { type: ''});
}
getState() {
return this.state.present;
}
dispatch(action) {
this.state = this.reducer(this.state, action);
}
}
Store
io.on('connection', (socket) => {
console.log('user connected');
io.emit('update', store.getState());
socket.on('dispatch', action => {
store.dispatch(action);
io.emit('update', store.getState());
});
socket.on('disconnect', function () {
console.log('user disconnected');
});
});
http.listen(5000, () => {
console.log('started on port 5000');
});
Socket.io
const BASE_URL = 'http://localhost:5000';
export class SocketService {
private socket;
private subjects = {};
constructor() {
this.socket = io(BASE_URL);
this.socket.on('update', data => this.next(data));
}
select(key) {
this.subjects[key] = new BehaviorSubject(null);
return this.subjects[key].asObservable();
}
next(data) {
for (const key in this.subjects) {
if (this.subjects.hasOwnProperty(key)) {
this.subjects[key].next(data[key]);
}
}
}
dispatch(action) {
this.socket.emit('dispatch', action);
}
}
SocketService
DEMO TIME!
https://github.com/onehungrymind/component-thin-clients
@simpulton
https://venturplex.com/
WE❤YOU!
Thanks!
1 of 64

Recommended

Codes by
CodesCodes
CodesOSit3
261 views33 slides
Rental by
RentalRental
RentalAhmad M
731 views4 slides
AngularJS, More Than Directives ! by
AngularJS, More Than Directives !AngularJS, More Than Directives !
AngularJS, More Than Directives !Gaurav Behere
317 views16 slides
Beyond the DOM: Sane Structure for JS Apps by
Beyond the DOM: Sane Structure for JS AppsBeyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS AppsRebecca Murphey
4K views43 slides
rules, events and workflow by
rules, events and workflowrules, events and workflow
rules, events and workflowMark Proctor
1.8K views126 slides
Inversion Of Control by
Inversion Of ControlInversion Of Control
Inversion Of ControlChad Hietala
1.2K views52 slides

More Related Content

Similar to Components Are the New Thin Client

FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ... by
FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...
FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...Haris Mahmood
446 views174 slides
Introduction to ECMAScript 2015 by
Introduction to ECMAScript 2015Introduction to ECMAScript 2015
Introduction to ECMAScript 2015Tomasz Dziuda
859 views149 slides
Drools Introduction by
Drools IntroductionDrools Introduction
Drools IntroductionJBug Italy
2.4K views28 slides
React.js: Beyond the Browser by
React.js: Beyond the BrowserReact.js: Beyond the Browser
React.js: Beyond the Browsergarbles
3.3K views70 slides
Ngrx slides by
Ngrx slidesNgrx slides
Ngrx slidesChristoffer Noring
2.8K views97 slides
Understanding redux by
Understanding reduxUnderstanding redux
Understanding reduxDavid Atchley
78 views44 slides

Similar to Components Are the New Thin Client(20)

FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ... by Haris Mahmood
FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...
FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...
Haris Mahmood446 views
Introduction to ECMAScript 2015 by Tomasz Dziuda
Introduction to ECMAScript 2015Introduction to ECMAScript 2015
Introduction to ECMAScript 2015
Tomasz Dziuda859 views
Drools Introduction by JBug Italy
Drools IntroductionDrools Introduction
Drools Introduction
JBug Italy2.4K views
React.js: Beyond the Browser by garbles
React.js: Beyond the BrowserReact.js: Beyond the Browser
React.js: Beyond the Browser
garbles3.3K views
Getting started with Elasticsearch and .NET by Tomas Jansson
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NET
Tomas Jansson35.7K views
Message-based communication patterns in distributed Akka applications by Andrii Lashchenko
Message-based communication patterns in distributed Akka applicationsMessage-based communication patterns in distributed Akka applications
Message-based communication patterns in distributed Akka applications
Andrii Lashchenko327 views
Javascript: the important bits by Chris Saylor
Javascript: the important bitsJavascript: the important bits
Javascript: the important bits
Chris Saylor957 views
10 Billion a Day, 100 Milliseconds Per: Monitoring Real-Time Bidding at AdRoll by Brian Troutwine
10 Billion a Day, 100 Milliseconds Per: Monitoring Real-Time Bidding at AdRoll10 Billion a Day, 100 Milliseconds Per: Monitoring Real-Time Bidding at AdRoll
10 Billion a Day, 100 Milliseconds Per: Monitoring Real-Time Bidding at AdRoll
Brian Troutwine8.8K views
Async Redux Actions With RxJS - React Rally 2016 by Ben Lesh
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016
Ben Lesh5.9K views
Buenos Aires Drools Expert Presentation by Mark Proctor
Buenos Aires Drools Expert PresentationBuenos Aires Drools Expert Presentation
Buenos Aires Drools Expert Presentation
Mark Proctor1.7K views
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM by Mario Fusco
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Mario Fusco5K views
MongoDB World 2019: Life In Stitch-es by MongoDB
MongoDB World 2019: Life In Stitch-esMongoDB World 2019: Life In Stitch-es
MongoDB World 2019: Life In Stitch-es
MongoDB184 views

More from Lukas Ruebbelke

ng-conf 2017: Angular Mischief Maker Slides by
ng-conf 2017: Angular Mischief Maker Slidesng-conf 2017: Angular Mischief Maker Slides
ng-conf 2017: Angular Mischief Maker SlidesLukas Ruebbelke
1.4K views30 slides
Embrace the Angular 2 Ethos in Angular 1.x by
Embrace the Angular 2 Ethos in Angular 1.xEmbrace the Angular 2 Ethos in Angular 1.x
Embrace the Angular 2 Ethos in Angular 1.xLukas Ruebbelke
5.3K views126 slides
Go Beast Mode with Realtime Reactive Interfaces in Angular 2 and Firebase by
Go Beast Mode with Realtime Reactive Interfaces in Angular 2 and FirebaseGo Beast Mode with Realtime Reactive Interfaces in Angular 2 and Firebase
Go Beast Mode with Realtime Reactive Interfaces in Angular 2 and FirebaseLukas Ruebbelke
2.4K views93 slides
Get that Corner Office with Angular 2 and Electron by
Get that Corner Office with Angular 2 and ElectronGet that Corner Office with Angular 2 and Electron
Get that Corner Office with Angular 2 and ElectronLukas Ruebbelke
33.5K views39 slides
The REAL Angular Keynote by
The REAL Angular KeynoteThe REAL Angular Keynote
The REAL Angular KeynoteLukas Ruebbelke
2.2K views74 slides
Impress Your Friends with EcmaScript 2015 by
Impress Your Friends with EcmaScript 2015Impress Your Friends with EcmaScript 2015
Impress Your Friends with EcmaScript 2015Lukas Ruebbelke
752 views79 slides

More from Lukas Ruebbelke(12)

ng-conf 2017: Angular Mischief Maker Slides by Lukas Ruebbelke
ng-conf 2017: Angular Mischief Maker Slidesng-conf 2017: Angular Mischief Maker Slides
ng-conf 2017: Angular Mischief Maker Slides
Lukas Ruebbelke1.4K views
Embrace the Angular 2 Ethos in Angular 1.x by Lukas Ruebbelke
Embrace the Angular 2 Ethos in Angular 1.xEmbrace the Angular 2 Ethos in Angular 1.x
Embrace the Angular 2 Ethos in Angular 1.x
Lukas Ruebbelke5.3K views
Go Beast Mode with Realtime Reactive Interfaces in Angular 2 and Firebase by Lukas Ruebbelke
Go Beast Mode with Realtime Reactive Interfaces in Angular 2 and FirebaseGo Beast Mode with Realtime Reactive Interfaces in Angular 2 and Firebase
Go Beast Mode with Realtime Reactive Interfaces in Angular 2 and Firebase
Lukas Ruebbelke2.4K views
Get that Corner Office with Angular 2 and Electron by Lukas Ruebbelke
Get that Corner Office with Angular 2 and ElectronGet that Corner Office with Angular 2 and Electron
Get that Corner Office with Angular 2 and Electron
Lukas Ruebbelke33.5K views
Impress Your Friends with EcmaScript 2015 by Lukas Ruebbelke
Impress Your Friends with EcmaScript 2015Impress Your Friends with EcmaScript 2015
Impress Your Friends with EcmaScript 2015
Lukas Ruebbelke752 views
Turn Your Designers Into Death Stars with Angular by Lukas Ruebbelke
Turn Your Designers Into Death Stars with AngularTurn Your Designers Into Death Stars with Angular
Turn Your Designers Into Death Stars with Angular
Lukas Ruebbelke4.9K views
Badges? We don't need no stinkin' badges! by Lukas Ruebbelke
Badges? We don't need no stinkin' badges!Badges? We don't need no stinkin' badges!
Badges? We don't need no stinkin' badges!
Lukas Ruebbelke2.1K views
Ionic Crash Course! Hack-a-ton SF by Lukas Ruebbelke
Ionic Crash Course! Hack-a-ton SFIonic Crash Course! Hack-a-ton SF
Ionic Crash Course! Hack-a-ton SF
Lukas Ruebbelke19.8K views
ngEurope 2014: Become a Realtime Cage Dragon with Firebase and AngularJS by Lukas Ruebbelke
ngEurope 2014: Become a Realtime Cage Dragon with Firebase and AngularJSngEurope 2014: Become a Realtime Cage Dragon with Firebase and AngularJS
ngEurope 2014: Become a Realtime Cage Dragon with Firebase and AngularJS
Lukas Ruebbelke1.8K views
AngularJS Directives - DSL for your HTML by Lukas Ruebbelke
AngularJS Directives - DSL for your HTMLAngularJS Directives - DSL for your HTML
AngularJS Directives - DSL for your HTML
Lukas Ruebbelke6.5K views

Recently uploaded

ict act 1.pptx by
ict act 1.pptxict act 1.pptx
ict act 1.pptxsanjaniarun08
13 views17 slides
Generic or specific? Making sensible software design decisions by
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsBert Jan Schrijver
6 views60 slides
A first look at MariaDB 11.x features and ideas on how to use them by
A first look at MariaDB 11.x features and ideas on how to use themA first look at MariaDB 11.x features and ideas on how to use them
A first look at MariaDB 11.x features and ideas on how to use themFederico Razzoli
45 views36 slides
Fleet Management Software in India by
Fleet Management Software in India Fleet Management Software in India
Fleet Management Software in India Fleetable
11 views1 slide
Roadmap y Novedades de producto by
Roadmap y Novedades de productoRoadmap y Novedades de producto
Roadmap y Novedades de productoNeo4j
50 views33 slides
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra... by
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra....NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra...
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra...Marc Müller
38 views62 slides

Recently uploaded(20)

Generic or specific? Making sensible software design decisions by Bert Jan Schrijver
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisions
A first look at MariaDB 11.x features and ideas on how to use them by Federico Razzoli
A first look at MariaDB 11.x features and ideas on how to use themA first look at MariaDB 11.x features and ideas on how to use them
A first look at MariaDB 11.x features and ideas on how to use them
Federico Razzoli45 views
Fleet Management Software in India by Fleetable
Fleet Management Software in India Fleet Management Software in India
Fleet Management Software in India
Fleetable11 views
Roadmap y Novedades de producto by Neo4j
Roadmap y Novedades de productoRoadmap y Novedades de producto
Roadmap y Novedades de producto
Neo4j50 views
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra... by Marc Müller
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra....NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra...
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra...
Marc Müller38 views
DSD-INT 2023 European Digital Twin Ocean and Delft3D FM - Dols by Deltares
DSD-INT 2023 European Digital Twin Ocean and Delft3D FM - DolsDSD-INT 2023 European Digital Twin Ocean and Delft3D FM - Dols
DSD-INT 2023 European Digital Twin Ocean and Delft3D FM - Dols
Deltares7 views
DSD-INT 2023 The Danube Hazardous Substances Model - Kovacs by Deltares
DSD-INT 2023 The Danube Hazardous Substances Model - KovacsDSD-INT 2023 The Danube Hazardous Substances Model - Kovacs
DSD-INT 2023 The Danube Hazardous Substances Model - Kovacs
Deltares8 views
Citi TechTalk Session 2: Kafka Deep Dive by confluent
Citi TechTalk Session 2: Kafka Deep DiveCiti TechTalk Session 2: Kafka Deep Dive
Citi TechTalk Session 2: Kafka Deep Dive
confluent17 views
Elevate your SAP landscape's efficiency and performance with HCL Workload Aut... by HCLSoftware
Elevate your SAP landscape's efficiency and performance with HCL Workload Aut...Elevate your SAP landscape's efficiency and performance with HCL Workload Aut...
Elevate your SAP landscape's efficiency and performance with HCL Workload Aut...
HCLSoftware6 views
MariaDB stored procedures and why they should be improved by Federico Razzoli
MariaDB stored procedures and why they should be improvedMariaDB stored procedures and why they should be improved
MariaDB stored procedures and why they should be improved
DSD-INT 2023 FloodAdapt - A decision-support tool for compound flood risk mit... by Deltares
DSD-INT 2023 FloodAdapt - A decision-support tool for compound flood risk mit...DSD-INT 2023 FloodAdapt - A decision-support tool for compound flood risk mit...
DSD-INT 2023 FloodAdapt - A decision-support tool for compound flood risk mit...
Deltares13 views
DSD-INT 2023 Wave-Current Interaction at Montrose Tidal Inlet System and Its ... by Deltares
DSD-INT 2023 Wave-Current Interaction at Montrose Tidal Inlet System and Its ...DSD-INT 2023 Wave-Current Interaction at Montrose Tidal Inlet System and Its ...
DSD-INT 2023 Wave-Current Interaction at Montrose Tidal Inlet System and Its ...
Deltares10 views
DSD-INT 2023 Simulating a falling apron in Delft3D 4 - Engineering Practice -... by Deltares
DSD-INT 2023 Simulating a falling apron in Delft3D 4 - Engineering Practice -...DSD-INT 2023 Simulating a falling apron in Delft3D 4 - Engineering Practice -...
DSD-INT 2023 Simulating a falling apron in Delft3D 4 - Engineering Practice -...
Deltares6 views
Advanced API Mocking Techniques by Dimpy Adhikary
Advanced API Mocking TechniquesAdvanced API Mocking Techniques
Advanced API Mocking Techniques
Dimpy Adhikary19 views
Software testing company in India.pptx by SakshiPatel82
Software testing company in India.pptxSoftware testing company in India.pptx
Software testing company in India.pptx
SakshiPatel827 views

Components Are the New Thin Client

  • 1. components are the new THIN CLIENT!
  • 3. DOM jQuery “Application” $( "form" ).submit(function( event ) { if ( $( "input:first" ).val() === "correct" ) { $( "span" ).text( "Validated..." ).show(); return; } $( "span" ).text( "Not valid!" ).show().fadeOut( 1000 ); event.preventDefault(); });
  • 4. DOM First Generation AngularJS Application CONTROLLER
  • 5. DOM Second Generation AngularJS Application CONTROLLER SERVICE DOM CONTROLLER
  • 8. In classical physics, if you know everything about a system at some instant of time, and you also know the equations that govern how the system changes then you can predict the future. That's what we mean when we say that the classical laws of physics are deterministic. If we can say the same thing, but with the past and future reversed, the same equations tell you everything about the past. Such a system is called reversible. The Theoretical Minimum by Leonard Susskind
  • 10. In classical physics, if you know everything about a system at some instant of time, and you also know the equations that govern how the system changes then you can predict the future. That's what we mean when we say that the classical laws of physics are deterministic. If we can say the same thing, but with the past and future reversed, the same equations tell you everything about the past. Such a system is called reversible. The Theoretical Minimum by Leonard Susskind
  • 12. In classical physics, if you know everything about a system at some instant of time, and you also know the equations that govern how the system changes then you can predict the future. That's what we mean when we say that the classical laws of physics are deterministic. If we can say the same thing, but with the past and future reversed, the same equations tell you everything about the past. Such a system is called reversible. The Theoretical Minimum by Leonard Susskind
  • 14. In classical physics, if you know everything about a system at some instant of time, and you also know the equations that govern how the system changes then you can predict the future. That's what we mean when we say that the classical laws of physics are deterministic. If we can say the same thing, but with the past and future reversed, the same equations tell you everything about the past. Such a system is called reversible. The Theoretical Minimum by Leonard Susskind
  • 15. In classical physics, if you know everything about a system at some instant of time, and you also know the equations that govern how the system changes then you can predict the future. That's what we mean when we say that the classical laws of physics are deterministic. If we can say the same thing, but with the past and future reversed, the same equations tell you everything about the past. Such a system is called reversible. The Theoretical Minimum by Leonard Susskind
  • 16. User Input and Response
  • 27. actions = [ {type: '[Client] Select', payload: {id: '1', firstName: 'John', lastName: 'Doe', company: 'Acme, Inc'}}, {type: '[Client] Select', payload: {id: '2', firstName: 'Jane', lastName: 'Smith', company: 'Super, Inc'}}, {type: '[Client] Select', payload: {id: '1', firstName: 'John', lastName: 'Doe', company: 'Acme, Inc'}}, {type: '[Client] Select', payload: {id: '2', firstName: 'Jane', lastName: 'Smith', company: 'Super, Inc'}}, {type: '[Client] Select', payload: {id: '1', firstName: 'John', lastName: 'Doe', company: 'Acme, Inc'}}, {type: '[Client] Select', payload: {id: '2', firstName: 'Jane', lastName: 'Smith', company: 'Super, Inc'}}, ]; index = 0; step() { this.index = this.index < this.actions.length - 1 ? this.index + 1 : 0; this.store.dispatch(this.actions[this.index]); } Manual Dispatch
  • 31. actions = [ {type: '[Client] Select', payload: {id: '1', firstName: 'John', lastName: 'Doe', company: 'Acme, Inc'}}, {type: '[Client] Select', payload: {id: '2', firstName: 'Jane', lastName: 'Smith', company: 'Super, Inc'}}, {type: '[Client] Select', payload: {id: '1', firstName: 'John', lastName: 'Doe', company: 'Acme, Inc'}}, {type: '[Client] Select', payload: {id: '2', firstName: 'Jane', lastName: 'Smith', company: 'Super, Inc'}}, {type: '[Client] Select', payload: {id: '1', firstName: 'John', lastName: 'Doe', company: 'Acme, Inc'}}, {type: '[Client] Select', payload: {id: '2', firstName: 'Jane', lastName: 'Smith', company: 'Super, Inc'}}, ]; cycle() { const result = Observable .from(this.actions) .zip(Observable.interval(this.timerInterval), (a, b) => a) ; result.subscribe(action => this.store.dispatch(action)); } Manual Cycle
  • 35. fetchSingle() { this.actionsService .single() .subscribe(action => this.action = JSON.stringify(action, null , 't')); } dispatch(action) { this.store.dispatch(JSON.parse(action)); } Dynamic Dispatch
  • 39. fetchAll() { this.actionsService .all() .subscribe(actions => this.rawActions = JSON.stringify(actions, null , 't')); } dispatchCycle(rawActions) { const actions = JSON.parse(rawActions); const result = Observable .from(actions) .zip(Observable.interval(this.timerInterval), (a, b) => a) ; result.subscribe((action: any) => this.store.dispatch(action)); } Dynamic Dispatch
  • 44. constructor( private actionsService: ActionsService, private store: Store<reducers.AppState>, private afs: AngularFirestore ) { this.remoteActions = afs.collection('actions'); } ngOnInit() { this.remoteActions.valueChanges() .skip(1) .subscribe((actions: any) => { this.store.dispatch(actions[0]); }); } dispatchRemote(action) { this.remoteActions.add(JSON.parse(action)); } Remote Dispatch
  • 47. export function undoable(reducer: ActionReducer<any>): ActionReducer<any> { // Call the reducer with empty action to populate the initial state const initialState = { past: [], present: reducer(undefined, { type: ''}), future: [] }; // Return a reducer that handles undo and redo return function (state = initialState, action) { const { past, present, future } = state; switch (action.type) { case 'UNDO': // UNDO LOGIC case 'REDO': // REDO LOGIC default: // REGULAR LOGIC } }; } Meta Reducer
  • 52. Space and Time: Thin Component
  • 53. const CLIENT_LOAD = '[Client] Load'; const CLIENT_CREATE = '[Client] Create'; const CLIENT_UPDATE = '[Client] Update'; const CLIENT_DELETE = '[Client] Delete'; const CLIENT_SELECT = '[Client] Select'; const CLIENT_CLEAR = '[Client] Clear'; Actions
  • 54. const reducer = (state = initialState, {type, payload}) => { switch (type) { case CLIENT_LOAD: return state; case CLIENT_SELECT: return selectClient(state, payload); case CLIENT_CREATE: return createClient(state, payload); case CLIENT_UPDATE: return updateClient(state, payload); case CLIENT_DELETE: return deleteClient(state, payload); case CLIENT_CLEAR: return clearClient(state, payload); default: return state; } }; const store = new Store(reducer, initialState); Reducer
  • 55. export class ClientsComponent implements OnInit { clients$: Observable<Client[]>; currentClient$: Observable<Client>; constructor(private store: Store) { this.clients$ = this.store.select('clients'); this.currentClient$ = this.store.select('currentClient'); } ngOnInit() { this.store.dispatch(new ClientActions.LoadAction()); this.resetCurrentClient(); } resetCurrentClient() { const newClient: Client = { id: null, firstName: '', lastName: '', company: '' }; this.store.dispatch(new ClientActions.SelectAction(newClient)); } } ClientsComponent
  • 56. class Store { constructor(reducer) { this.reducer = reducer; this.state = reducer(undefined, { type: ''}); } getState() { return this.state.present; } dispatch(action) { this.state = this.reducer(this.state, action); } } Store
  • 57. io.on('connection', (socket) => { console.log('user connected'); io.emit('update', store.getState()); socket.on('dispatch', action => { store.dispatch(action); io.emit('update', store.getState()); }); socket.on('disconnect', function () { console.log('user disconnected'); }); }); http.listen(5000, () => { console.log('started on port 5000'); }); Socket.io
  • 58. const BASE_URL = 'http://localhost:5000'; export class SocketService { private socket; private subjects = {}; constructor() { this.socket = io(BASE_URL); this.socket.on('update', data => this.next(data)); } select(key) { this.subjects[key] = new BehaviorSubject(null); return this.subjects[key].asObservable(); } next(data) { for (const key in this.subjects) { if (this.subjects.hasOwnProperty(key)) { this.subjects[key].next(data[key]); } } } dispatch(action) { this.socket.emit('dispatch', action); } } SocketService