Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does ImmutableJS work with Angular 2?

I've been using ImmutableJS with Angular 2 for some time, because of it's performance benefits in change detection. See here.

However, I'm not quite sure, why Immutable works with Angular 2 by default. How does it know how to iterate over the values and display them, when there's no explicit array? Does it just call toJS() every time it accesses the values of the collection? Does it implement some kind of method that Angular 2 automatically calls?

And if so, is there a way to define your own collections which also implement this method?

An example:

Component({
    selector: 'list',
    template: '<ul><li *ngFor="#item of items">{{ item.id }}</li></ul>',
    directives: [CORE_DIRECTIVES]
})
export class SiteComponent { 
    items: Immutable.List<Item>;
}
like image 222
Luka Jacobowitz Avatar asked Mar 14 '16 15:03

Luka Jacobowitz


People also ask

Why use immutable objects Angular?

Undoubtedly, you should stick to immutable data structures in Angular applications. Not only does it allow you to improve a runtime performance by using the OnPush change detection strategy, but it also prevents you from getting into troubles of having stale data rendered in the view.

What are immutable objects in angular?

Immutability is a design pattern where something can't be modified after being instantiated. If we want to change the value of that thing, we must recreate it with the new value instead. Some JavaScript types are immutable and some are mutable, meaning their value can change without having to recreate it.

What is mutable and immutable in angular?

A mutable object can be changed after it's created, and an immutable object can't.


1 Answers

I'm not an Angular user, but I think it's quite easy to see what happens underneath: I'd assume that

ngFor="#item of items"

is transformed to some equivalent of for..of cycle. This construct can be used for iterating over Arrays, but also can be used with any iterable in general. (And yes, immutable.List correctly implements iterable protocol)

Some fine resources:

iterable protocol on SO:

Checking whether something is iterable

iterable protocol in depth:

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Iteration_protocols

Finally:

If you want to be 100% sure, create a simple structure that is iterable, but it's neither Array nor Immutable.List, so Angular cannot know how to iterate it but to use iterable protocol (requires babel or new version of node) :

'use strict'
let obj = {}
// obj is iterable with values 1, 2, 3
obj[Symbol.iterator] = function() {
  console.log('Yes, I am using the iterable protocol indeed')
  return [1, 2, 3][Symbol.iterator]()
}
for (let i of obj) {
  console.log(i)  // prints 1, 2, 3
}

Now if you use this structure instead of immutable.List, you can easily see that the iterator is called.

like image 84
Tomas Kulich Avatar answered Oct 21 '22 09:10

Tomas Kulich