# @ancestorAttribute

Copies the value of an attribute from the nearest element that carries it (the host itself, then its ancestors, across shadow roots) into a class property. Use it to pick up a scope such as `dataProvider` without passing it down by hand, typically to feed a dynamic key of [@subscribe](/docs/decorators/subscribe).

## Import

<sonic-code language="typescript">
  <template>
import { ancestorAttribute } from "@supersoniks/concorde/decorators";

@ancestorAttribute("dataProvider")
dataProvider: string | null = null;
  </template>
</sonic-code>

## Read once at connect

By default the value is read once, just before the component's `connectedCallback`, and never updated. The closest element with the attribute wins. If no ancestor has it, the property keeps its initial value.

<sonic-code>
  <template>
<div dataProvider="flights.CN001" gate="B12">
  <docs-demo-sources for="demo-ancestor-attribute"></docs-demo-sources>
  <demo-ancestor-attribute></demo-ancestor-attribute>
</div>
  </template>
</sonic-code>

An attribute present without a value (`<div gate>`) resolves to `""`. A camelCase name also matches its lowercase form (`dataProvider` and `dataprovider`).

## Follow DOM changes

With `{ dynamic: true }`, the property stays in sync while the component is connected: when an ancestor changes the attribute, when a closer ancestor gains or loses it, and when the component is moved. When no ancestor has the attribute, the property becomes `null`. Add `@state()` so Lit re-renders on each assignment.

<sonic-code language="typescript">
  <template>
@ancestorAttribute("dataProvider", { dynamic: true })
@state()
dataProvider: string | null = null;
  </template>
</sonic-code>

Change the parent or outer value, insert a closer wrapper, or remove an attribute: the child always shows the nearest one.

<sonic-code>
  <template>
    <docs-demo-sources for="demo-ancestor-attribute-dynamic-section"></docs-demo-sources>
    <demo-ancestor-attribute-dynamic-section></demo-ancestor-attribute-dynamic-section>
  </template>
</sonic-code>

Keys of [@subscribe](/docs/decorators/subscribe) and [@bind](/docs/decorators/bind) that use the property as a placeholder (`"${dataProvider}"`) are re-resolved on each change.

## API reference

| Argument | Type | Description |
|----------|------|-------------|
| `attributeName` | `string` | Attribute to look up on the host, then on its ancestors |
| `options.dynamic` | `boolean` (default `false`) | Keep the property in sync with attribute changes and reparenting until disconnect; assigns `null` when no ancestor has the attribute |
