Independent Consultant & Software Architect
Trainer, Speaker, JS/TS Expert
ArchitekturaNaFroncie.pl (ANF)
Warsaw, PL
tomasz (at) ducin.dev
@tomasz_ducin
(resource: freelancer.com contest)
in AngularJS
angular.module('myMod', ['ngRoute'])
.service('DepartmentsModel', ["$http", "baseURL", function ($http, baseURL) {
this.getCollection = function (start, end) {
return $http.get(baseURL + "departments", ...)
};
}])
.component('userPage', {
template: require("./templates/user-page.html"),
controller: function ($scope, UserContext, DepartmentsModel) {
var ctrl = this;
...
this.fetchDepartments = function () {
DepartmentsModel.getCollection().then(function (response) {
ctrl.departments = response.data;
});
};
}
})
in AngularJS
angular.module('myMod', ['ngRoute'])
.service('DepartmentsModel', ["$http", "baseURL", function ($http, baseURL) {
this.getCollection = function (start, end) {
return $http.get(baseURL + "departments", ...)
};
}])
.component('userPage', {
template: require("./templates/user-page.html"),
controller: function ($scope, UserContext, DepartmentsModel) {
var ctrl = this;
...
this.fetchDepartments = function () {
DepartmentsModel.getCollection().then(function (response) {
ctrl.departments = response.data;
});
};
}
})
<script src="angular.min.js"></script>
<script src="department-service.js"></script>
<script src="user-page-component.js"></script>
...
(another hundreds scripts)
in AngularJS
<p>First name: {{ firstName }}</p>
// in template
<input ng-model="firstName">
// OR
// in controller
$scope.firstName = "John";
in AngularJS
Service
Declarative, State-driven UI Development
export class Heading extends React.Component {
render(){
return <div>
<h1>{ props.heading }</h1>
<img src={ props.imageURL } />
</div>
}
}
export class Heading extends React.Component {
state = {
count: 0
}
render(){
return <div>
<h1>{ props.heading } { this.state.count }</h1>
<img src={ props.imageURL } />
<button onClick={this.handleClick}
<ChildComponent count={this.state.count} />
</div>
}
handleClick = () => {
this.setState(state => { count: state.count + 1 })
}
}
export const Heading = (props) =>
<div>
<h1>{ props.heading }</h1>
<img src={ props.imageURL } />
</div>
export class Heading extends React.Component {
render(){
return <div>
<h1>{ props.heading }</h1>
<img src={ props.imageURL } />
</div>
}
}
this
)passing functions down to the child
in browsers
<body>
<div>
<div>
<span>
<div>
<img>
<h1>
<p>
in React
<body>
<div>
<div>
<span>
<div>
<img>
<h1>
<p>
export const Heading = (props) =>
<div>
<h1>{ props.heading }</h1>
<img src={ props.imageURL } />
</div>
function Heading(props) {
return React.createElement("div", null,
React.createElement("h1", null, props.heading),
React.createElement("img", {
src: props.imageURL
})
);
};
render phase (virtual) + commit phase (DOM repaint)
in React
state of a parent becomes props (properties) of children
in React (immutability)
export const Heading = (props) =>
<div>
<h1>{ props.heading }</h1>
<img src={ props.imageURL } />
</div>
export class Heading extends React.Component {
render(){
return <div>
<h1>{ props.heading }</h1>
<img src={ props.imageURL } />
</div>
}
}
export const Heading = React.memo((props) =>
<div>
<h1>{ props.heading }</h1>
<img src={ props.imageURL } />
</div>)
export class Heading extends React.PureComponent {
render(){
return <div>
<h1>{ props.heading }</h1>
<img src={ props.imageURL } />
</div>
}
}
private component state or shared
(!) LOTS OF native JS imports and exports
@NgModule({
declarations: [
AppComponent,
ItemComponent
],
imports: [
BrowserModule,
FormsModule,
HttpClientModule
],
exports: [
ItemComponent
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
local declarations of components, pipes
components, pipes to be available outside
the main view
sometimes you need those :|
import other NgModules
export class MyClass { ... }
export const instance = new MyClass()
export const n = 1
export const literal = {
value: 1
}
export const getLiteral = () => ({
value: 1
})
export const getLiteralSingleton = singleton(getLiteral)
import { getLiteralSingleton } from './here'
getLiteralSingleton().doThings()
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'app-voter',
template: `
<h4>{{name}}</h4>
<button (click)="vote(true)" [disabled]="voted">Agree</button>
<button (click)="vote(false)" [disabled]="voted">Disagree</button>
`
})
export class VoterComponent {
@Input() name: string;
@Output() onVoted = new EventEmitter<boolean>();
voted = false;
vote(agreed: boolean) {
this.onVoted.emit(agreed);
this.voted = true;
}
}
async task ⚙️
async task ⚙️
async task ⚙️
in Angular
let rate = 3.94;
let amount = 1000;
let exchange = amount / rate; // 253.80
rate = 3.97;
exchange // DESYNC, sync manually!
let rate$ = 3.94;
let amount$ = 1000;
let exchange$ = amount$ / rate$; // 253.80
rate$ = 3.97;
exchange$ // 251.89
let rate$ = 3.94;
let amount$ = 1000;
let exchange$ = combineLatest(amount$, rate$,
(amount, rate) => amount / rate);
let rate$ = 3.94;
let amount$ = 1000;
let exchange$ = combineLatest(amount$, rate$,
(amount, rate) => amount / rate);
// rate$ == 3.97 ---> exchange$ == 251.89
Reactive Extensions (RX)
redefine what a variable is
<script>
const price = 9.99
let quantity = 0;
$: totalPrice = quantity * price;
function handleClick() {
quantity += 1;
}
</script>
(mockup: https://dribbble.com/shots/6475026-Push-Notifications-Delivered)
(mockup: https://dribbble.com/shots/6475026-Push-Notifications-Delivered)
(mockup: https://dribbble.com/shots/6475026-Push-Notifications-Delivered)