Updater

A DOM updater that binds structured data objects to templates and rendered document fragments.

Import
the javascript logo
import { Updater } from "@schukai/monster/source/dom/updater.mjs";
Source
the git logo
Package
the npm logo
Since
1.8.0

Introduction

The Updater is the central binding layer between structured data and DOM markup in Monster. It reads declarative data-monster-* attributes, updates text, attributes, properties and repeated structures, and can also write values back into the subject when event processing is enabled.

Quick Start



import { Updater } from "@schukai/monster/source/dom/updater.mjs";

const data = { headline: "Hello World" };
const updater = new Updater(document.body, data);

updater.run().then(() => updater.enableEventProcessing());

Core Surfaces

AttributePurpose
data-monster-replaceReplaces text-like content from a pipe result such as path:headline.
data-monster-patchPatches child content in place and is safer for richer DOM fragments than plain replacement.
data-monster-patch-keyDefines the stable key for patched list children so DOM nodes can be reused instead of recreated.
data-monster-patch-renderSelects how patched list values are rendered before keyed reconciliation happens.
data-monster-attributesMaps results into DOM attributes such as title, href or aria-*.
data-monster-propertiesWrites values into DOM properties or Monster control options, for example value, checked or option:label.
data-monster-bindBinds form input back to a subject path and works together with enableEventProcessing().
data-monster-bind-typeCasts bound values, for example to number, boolean, json or arrays.
data-monster-insertClones a named template for iterable data, usually with key path:items.
data-monster-insert-referenceInternal marker for inserted nodes; useful to understand when debugging repeated structures.
data-monster-removeMarks nodes that should be cleared before new repeated items are rendered.
data-monster-select-thisForces updates against the selected node itself when the direct diff would otherwise skip it.

What Developers Usually Miss

  • data-monster-properties is the right tool for control properties and option paths; do not misuse data-monster-attributes for values that live as JS properties.
  • data-monster-patch and keyed patching matter for preserving DOM state in lists.
  • data-monster-bind only writes back once event processing is enabled.
  • Insert and patch features are often combined with templates; plain replacement is not enough for richer repeated content.

Binding and Input Sync

Use data-monster-bind for inputs and call enableEventProcessing() to write user input back to the subject. If you only need a one-time read, call retrieve().

Template Insertion and Patching

The insert feature clones a document template for each entry in a list and rewrites internal paths so nested bindings point to the correct item. For richer child structures, combine that with patching and a stable data-monster-patch-key so nodes are reconciled instead of replaced blindly.

Simple Example

import { Updater } from "@schukai/monster/source/dom/updater.mjs";

const container = document.getElementById("updater-demo");

const data = {
    headline: "Hello World"
};

const updater = new Updater(container, data);
updater.run().then(() => updater.enableEventProcessing());

const subject = updater.getSubject();
setTimeout(() => {
    subject.headline = "Hello World!";
}, 1000);
Open in playground

Properties, Patching And Keyed List Rendering

import { Updater } from "@schukai/monster/source/dom/updater.mjs";

const container = document.getElementById("updater-advanced-demo");

const data = {
    status: {
        label: "Deploy Ready",
        description: "Current deployment state",
    },
    tasks: [
        { id: "t1", title: "Review docs", state: "done" },
        { id: "t2", title: "Regenerate pages", state: "running" },
    ],
};

const updater = new Updater(container, data);
await updater.run();
updater.enableEventProcessing();

const subject = updater.getSubject();

setTimeout(() => {
    subject.status.label = "Deploy Started";
    subject.status.description = "Deployment was triggered";
    subject.tasks = [
        { id: "t1", title: "Review docs", state: "done" },
        { id: "t2", title: "Regenerate pages", state: "done" },
        { id: "t3", title: "Publish release", state: "queued" },
    ];
}, 1200);
Open in playground

Attribute And ARIA Mapping

import { Updater } from "@schukai/monster/source/dom/updater.mjs";

const updater = new Updater(document.getElementById("updater-attributes-demo"), {
    link: {
        href: "https://monsterjs.org/getting-started.html",
        title: "Open the getting started guide",
        label: "Read the Monster getting started guide",
        text: "Open getting started",
    },
});

await updater.run();
Open in playground

Bound Value Casting

import { Updater } from "@schukai/monster/source/dom/updater.mjs";

const output = document.getElementById("bind-types-output");
const updater = new Updater(document.getElementById("updater-bind-types-demo"), {
    count: 0,
    enabled: false,
    config: {},
});

await updater.run();
updater.enableEventProcessing();

document.getElementById("bind-types-run").addEventListener("click", () => {
    output.textContent = JSON.stringify(updater.getSubject(), null, 2);
});
Open in playground

One Time Retrieval Without Live Events

import { Updater } from "@schukai/monster/source/dom/updater.mjs";

const output = document.getElementById("retrieve-output");
const updater = new Updater(document.getElementById("updater-retrieve-demo"), {
    headline: "Original title",
});

await updater.run();

document.getElementById("retrieve-run").addEventListener("click", () => {
    updater.retrieve();
    output.textContent = JSON.stringify(updater.getSubject(), null, 2);
});
Open in playground

Template Insertion For Iterable Data

import { Updater } from "@schukai/monster/source/dom/updater.mjs";

const updater = new Updater(document.getElementById("updater-insert-demo"), {
    items: [
        { title: "Prepare release", state: "done" },
        { title: "Write docs", state: "running" },
    ],
});

await updater.run();
Open in playground

Custom Pipe Callbacks

import { Updater } from "@schukai/monster/source/dom/updater.mjs";

const updater = new Updater(document.getElementById("updater-callbacks-demo"), {
    name: "monster updater",
});

updater.setCallback("upper", (value) => String(value).toUpperCase());
await updater.run();
Open in playground

Batched Update Processing

import { Updater } from "@schukai/monster/source/dom/updater.mjs";

const output = document.getElementById("batch-output");
const updater = new Updater(document.getElementById("updater-batch-demo"), {
    title: "Initial title",
    summary: "Initial summary",
});

updater.setBatchUpdates(true);
await updater.run();

const subject = updater.getSubject();
subject.title = "Batched title";
subject.summary = "Batched summary";

output.textContent = JSON.stringify(subject, null, 2);
Open in playground

Property Updates On Native Controls

import { Updater } from "@schukai/monster/source/dom/updater.mjs";

const updater = new Updater(document.getElementById("updater-control-properties-demo"), {
    score: 72,
    max: 100,
    label: "72 of 100 points",
});

await updater.run();
Open in playground

Multi Select Array Binding

import { Updater } from "@schukai/monster/source/dom/updater.mjs";

const output = document.getElementById("multiselect-output");
const updater = new Updater(document.getElementById("updater-multiselect-demo"), {
    teams: [],
});

await updater.run();
updater.enableEventProcessing();

document.getElementById("multiselect-run").addEventListener("click", () => {
    output.textContent = JSON.stringify(updater.getSubject(), null, 2);
});
Open in playground

Exported

Updater, addObjectWithUpdaterToElement

Derived from

Base

Options

The Options listed in this section are defined directly within the class. This class is derived from several parent classes. Therefore, it inherits Options from these parent classes. If you cannot find a specific Options in this list, we recommend consulting the documentation of the Base.

Option
Type
Default
Description
-/-

Properties

The Properties listed in this section are defined directly within the class. This class is derived from several parent classes. Therefore, it inherits Properties from these parent classes. If you cannot find a specific Properties in this list, we recommend consulting the documentation of the Base.

Methods

The methods listed in this section are defined directly within the class. This class is derived from several parent classes. Therefore, it inherits methods from these parent classes. If you cannot find a specific method in this list, we recommend consulting the documentation of the Base.

Constructor

constructor(element,subject)1.8.0
Parameters
  • element {htmlelement}: element
  • subject {object|proxyobserver|undefined}: subject
Throws
  • {TypeError} value is not a object
  • {TypeError} value is not an instance of HTMLElement

Behavioral methods

disableEventProcessing()1.9.0
Returns
  • {Updater}
This method turns off the magic or who loves it more profane it removes the eventListener.
enableEventProcessing()1.9.0
Returns
  • {Updater}
Throws
  • {Error} the bind argument must start as a value with a path
With this method, the eventlisteners are hooked in and the magic begins.
updater.run().then(() => {
  updater.enableEventProcessing();
});

State query methods

isDisposed()1.9.0
Returns
  • {Updater}
This method turns off the magic or who loves it more profane it removes the eventListener.

Structural methods

getSubject()1.8.0
Returns
  • {Proxy}
If you have passed a ProxyObserver in the constructor, you will get the object that the ProxyObserver manages here. However, if you passed a simple object, here you will get a proxy for that object. For changes, the ProxyObserver must be used.
setBatchUpdates(enabled)4.104.0
Parameters
  • enabled {boolean}: enabled
Returns
  • {Updater}
Enable or disable batched update processing.
setCallback(name,callback)
Parameters
  • name {string}: name
  • callback {function}: callback
Returns
  • {Transformer}
Throws
  • {TypeError} value is not a string
  • {TypeError} value is not a function
This method can be used to register commands that can be called via call: instruction. This can be used to provide a pipe with its own functionality.
setEventTypes(types)1.9.0
Parameters
  • types {array}: types
Returns
  • {Updater}
Defaults: 'keyup', 'click', 'change', 'drop', 'touchend'

Other methods

[applyChangeSymbol](change)
Parameters
  • change
[processQueueSymbol]()
Returns
  • {Promise}
dispose()1.9.0
Returns
  • {Updater}
This method turns off the magic or who loves it more profane it removes the eventListener.
retrieve()1.27.0
Returns
  • {Monster.DOM.Updater}
Gets the values of bound elements and changes them in subject
run()
Returns
  • {Promise}
The run method must be called for the update to start working. The method ensures that changes are detected.
updater.run().then(() => {
  updater.enableEventProcessing();
});

Events

This component does not fire any public events. It may fire events that are inherited from its parent classes.

The current width of the area is too small to display the content correctly.