Bloc Pattern in Javascript

Posted: 23 Jan 2024. Last modified on 14-Feb-25.

This article will take about 2 minutes to read.



Demo

The Bloc pattern is used extensively in Flutter. It’s a way of doing reactive state management.

The code for this is so simple that we can include it all here.

First, we need to define a class which contains state, and the means to observe it.

const { Subject } = rxjs;

class CounterBloc {
    constructor() {
        this.counter = 0;
        this.counterSubject = new Subject();
    }

    incrementCounter() {
        this.counter++;
        this.counterSubject.next(this.counter);
    }

    dispose() {
        this.counterSubject.complete();
    }
}

Then we need to create a component which depends on the bloc.


class CounterComponent extends HTMLElement {
    constructor() {
        super();
    }

    setBloc(bloc) {
        this.bloc = bloc;
    }

    connectedCallback() {
        this.className = "counter-element"

        const button = document.createElement('button');
        button.textContent = 'Click me';
        button.onclick = () => {
            this.bloc.incrementCounter();
        };

        const output = document.createElement('span');

        this.bloc.counterSubject.subscribe((value) => {
            output.textContent = `Counter: ${value}`;
        });

        this.appendChild(button);
        this.appendChild(output);
    }
}

customElements.define('counter-component', CounterComponent);

Then at the call site, we define 2 new components which share the same Bloc. They will each be incremented at the same time.

<div id="wrapper"></div>
<script>
    const wrapper = document.getElementById("wrapper")
    const bloc = new CounterBloc();

    const counter1 = document.createElement('counter-component');
    counter1.setBloc(bloc);
    wrapper.appendChild(counter1);

    const counter2 = document.createElement('counter-component');
    counter2.setBloc(bloc);
    wrapper.appendChild(counter2);
</script>

All in all, this demonstrates shared reactive state.



VanillaJS