Concorde documentation · same URL (interactive) · llms.txt

Concorde decorator — @bind. @bind(key) keeps a class property and one path of the DataProvider store in sync. With { reflect: true } the sync goes both ways: the property follows the store, and each assignment is written back to Doc ID: docs/decorators/bind. Keywords: Concorde, supersoniks, docs/decorators/bind, bind, @bind, decorator, @bind(key), { reflect: true }, @state(), reflect: true, set(), reflect, @subscribe, ${index}. URL: https://concorde.supersoniks.org/docs/decorators/bind.

@bind

@bind(key) keeps a class property and one path of the DataProvider store in sync. With { reflect: true } the sync goes both ways: the property follows the store, and each assignment is written back to it. For one direction only, use the complementary decorators: @subscribe to read, @publish to write. See Data flow for the overall model.

Import

import { bind } from "@supersoniks/concorde/decorators";
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";

type Flight = { flight: string; gate: string; boarded: number };
const flightKey = new DataProviderKey<Flight>("flight");

@bind(flightKey.boarded, { reflect: true })
@state()
boarded = 0;

Basic usage

The key is a DataProviderKey: TypeScript checks that the property type matches T at that path. The property updates each time the store value changes. Add @state() so Lit re-renders.

<docs-demo-sources for="demo-bind"></docs-demo-sources>
    <demo-bind></demo-bind>

Reflect

With reflect: true, each assignment to the property calls set() at the key path, so every other subscriber sees the new value. An internal guard prevents update loops. Without reflect (the default), assigning the property does not touch the store, and @bind behaves like @subscribe.

<docs-demo-sources for="demo-bind-reflect"></docs-demo-sources>
    <demo-bind-reflect></demo-bind-reflect>

Dynamic path

Placeholders such as ${index} are resolved from properties of the same component, and @bind re-subscribes when they change. Declare them in the key's second generic and write them in a plain string, not a backtick template literal. While a placeholder is null or undefined the binding is inactive; { skipEmptyPlaceholder: true } also waits on "". Full rules: Dynamic paths.

const personKey = new DataProviderKey&lt;Person, { dataProvider: string; index: number }&gt;(
  "${dataProvider}.${index}",
);

@bind(personKey)
@state()
person: Person | null = null;
<docs-demo-sources for="demo-bind-dynamic"></docs-demo-sources>
    <demo-bind-dynamic></demo-bind-dynamic>

Lifecycle

The decorator subscribes in connectedCallback and unsubscribes in disconnectedCallback. It works on any element with that lifecycle (LitElement, the Subscriber mixin).

API reference

Argument Type Description
key DataProviderKey<T> Store path to bind. Supports ${prop} placeholders
options.reflect boolean (default false) Write local assignments back to the store
options.skipEmptyPlaceholder boolean (default false) Treat a placeholder resolved to "" as not ready