4. • Original object remains.
• Handle properties through set and get.
• Encourages object mutation.
• Computed properties, observers.
T H E E M B E R O B J E C T ( PA R M E N I D E S )
5. • Never modify an object.
• Create new objects all the time.
• Different solutions due constrains.
T H E H E R A C L I T U S WAY ( I M M U TA B I L I T Y )
6. • Tracking changes is easier.
• Simpler state management.
I M M U TA B L E D ATA F L O W S : W H Y ?
7. D E S I G N I N G
I M M U TA B L E D ATA F L O W S
I N E M B E R
J O R G E L A I N F I E S TA
8. • Simple form with text fields of
personal information.
• DDAU
B A S I C E X A M P L E
9. <label>Name:</label>
{{one-way-input (get person 'name') update=(action 'update' 'name')}}
<br>
<label>Surname:</label>
{{one-way-input (get person 'surname') update=(action 'update' 'surname')}}
<br>
<label>Email:</label>
{{one-way-input (get person 'email') update=(action 'update' 'email')}}
t e m p l a t e s / c o m p o n e n t s / u s e r - f o r m . h b s
10. import Ember from 'ember';
export default Ember.Component.extend({
actions: {
update(field, value) {
this.get('onUpdate')(field, value);
}
}
});
c o m p o n e n t s / u s e r - f o r m . j s
11. updateUser(field, value) {
let user = this.get('user');
set(user, field, value);
}
r e s p o n s i b l e p a r e n t
mutating object
12. updateUser(field, value) {
let user = {...this.get('user')};
set(user, field, value);
this.set('user', user);
}
r e s p o n s i b l e p a r e n t
not mutating
original object
13. updateUser(field, newData) {
let user = this.get('user');
this.set('user', { ...user, [field]: newData });
}
r e s p o n s i b l e p a r e n t
Immutability
15. Update the parent with the same
data type that they provided.
C O N T R A C T S F O R C O M P O S I T I O N
interface ImmutableComponentProps<E> {
value: E;
onUpdate: (updatedValue: E) => void
}
16. import Ember from 'ember';
export default Ember.Component.extend({
actions: {
update(field, value) {
this.get('onUpdate')({
[field]: value
});
}
}
});
c o m p o n e n t s / u s e r - f o r m . j s
17. updateUser(newData) {
let user = this.get('user');
this.set('user', { ...user, ...newData });
}
r e s p o n s i b l e p a r e n t
Immutability
22. W O R K I N G W I T H A R R AY S
★ map
★ reduce
★ filter
★ find
★ slice
• splice
• sort
• push
• Mutable array methods
in Ember
MutationsNo mutations
23. actions: {
addItem(newElement) {
let value = this.get('value');
this.get('onUpdate')([
...value,
newElement
]);
},
removeItem(index) {
let value = this.get('value');
this.get('onUpdate')([
...value.slice(0, index),
...value.slice(index + 1)
]);
}
}
c o m p o n e n t s / t o d o - l i s t . j s
24. updateList(newList) {
// Some treatment and processing?
this.set('list', newList);
}
r e s p o n s i b l e p a r e n t
30. import Component, { tracked } from '@glimmer/component';
export default class ImmutabilityGlimmer extends Component {
@tracked user = {
name: 'Joe',
surname: 'Schreier'
};
@tracked('user')
get fullName() {
let { name, surname } = this.user;
return `${name} ${surname}`;
}
}
s o m e g l i m m e r c o m p o n e n t