Immutability
ActiveJS Units that store primitive values i.e. BoolUnit, NumUnit, and StringUnit are automatically immutable because these Units deal with primitive values, and primitive values in JavaScript are immutable.
The Units that store non-primitive values i.e. DictUnit, ListUnit, and GenericUnit can be made immutable by just setting a configuration flag to true
.
Creating an immutable Unit
Making all Units immutable
All the Units can be made immutable by default, by setting a flag in the global configuration.
Efficiency and precautions
Immutability brings a lot of benefits, such as predictability, and improving JS frameworks' rendering performance by avoiding the need for dirty checking, etc.
However, if not used correctly, there is a chance that you might run into performance bottlenecks.
Although ActiveJS takes most of these precautions on your behalf and tries to give the best experience and performance without any significant change in development practices and flow. There are still a few things that you might want to be aware of.
When a Unit is immutable:
Avoid using the static value access as much as you can, since the
value()
method creates a new copy every time you call it. Instead use Observable value, which is shared with all the observers.Don't use the
value()
method directly in an Angular template, otherwise on every change detection there will be a new copy. Instead use the Units withasync
pipe.Prefer using ListUnit and DictUnit over GenericUnit, and use methods like
set
,get
,findByProp
, etc. that do not create a copy on their invocation.When dispatching a value using the
dispatch
method, you can mutate the value provided to the value-producer function, because it's a copy. And if you don't intend to use the current value to create a new value, just pass the new value directly so that the Unit doesn't waste a copy.When you need to invoke a method like
find
which uses a predicate method to loop over stored items, if you can ensure that you won't mutate the value, you can invoke these methods on raw value instead, without creating a copy by usingUnit.rawValue()
e.g:ListUnit.rawValue().find(item => item.name.startsWith('A'))
In general, just try to avoid methods that create a new copy, and use alternative methods that do not. You can check this information in the documentation available within the library, or you can refer to API reference.
Supported data types
It's advised to put only serializable data types in an immutable Unit, non-serializable data types like Map, Set, etc. are not cloned by ActiveJS. They will be left as is and will be shared by reference (i.e. will be mutable).
All the primitive data types like boolean
, number
, etc. are supported by default, along with array
and simple object
that can be cloned by ActiveJS, and hence can be guaranteed to be immutable.
Last updated