Documentation

Report Edit

Immer.js Integration

CxJS requires all data to be immutable. Each change (update) operation is required to return a new object. This can be very challenging with complex and deeply nested data models, especially for developers who are not used to that.

Immer.js can help greatly with that, especially in combination with typed data models.

In order to use Immer.js, you need to install immer and cx-immer npm packages.

npm install immer cx-immer

Once installed you should enable Immer in CxJS stores. This should be done on application startup.

import { enableImmerMutate } from "cx-immer";

enableImmerMutate();

Once this is implemented you can use the mutate method for updating data in the store.

Controller.ts
export default class extends Controller<PageModel> {
    // Example 1: Before (immutable operation)
    onAddTodo(text: string) {
        this.store.update(
            $page.todos,
            todos => [...todos, { id: uid(), text, completed: false }]
        );
    }

    // Example 1: After
    onAddTodo(text: string) {
        this.store.mutate(
            $page.todos,
            todos => {
                // No issues with mutating data directly inside the mutate method
                todos.push({ id: uid(), text, completed: false });
                // It's not required to return anything
            }
        );
    }

    // Example 2: Before
    onMarkComplete(id: string) {
        this.store.update(
            $page.todos,
            updateArray,
            todo => ({ ...todo, completed: true }),
            todo => todo.id == id
        );
    }

    // Example 2: After
    onMarkComplete(id: string) {
        this.store.mutate(
            $page.todos,
            todos => {
                let todo = todos.find(t => t.id === id);
                todo.completed = true;
            }
        );
    }
}
Copied!