| `src` | `String` | | The source to subscribe to updates to, this should map to a string based URI |
| `loading` | `String` | eager | Allows the browser to defer loading offscreen DataSources (`eager\|lazy`). Setting to `lazy` only loads the data when the DataSource is visible in the DOM (inc. `display: none\|block;`) |
| `onchange` | `Function` | | The action to fire when the data changes. Emits an Event-like object with a `data` property containing the data. |
| `onerror` | `Function` | | The action to fire when an error occurs. Emits ErrorEvent object with an `error` property containing the Error. |
The component takes a `src` or an identifier (a uri) for some data and then emits `onchange` events whenever that data changes. If an error occurs whilst listening for data changes, an `onerror` event is emitted.
Setting `@loading="lazy"` uses `IntersectionObserver` to activate/deactive event emitting until the `<DataSource />` element is displayed in the DOM. This means you can use CSS `display: none|block;` to control the loading and stopping loading of data for usage with CSS based tabs and such-like.
Consuls HTTP API DataSources use Consul's blocking query support for live updating of data.
Behind the scenes in the Consul UI we map URIs back to our `ember-data` backed `Repositories` meaning we can essentially redesign the URIs used for our data to more closely fit our needs. For example we currently require that **all** HTTP API URIs begin with `/dc/nspace/` values whether they require them or not.
`DataSource` is not just restricted to HTTP API data, and can be configured to listen for data changes using a variety of methods and sources. For example we have also configured `DataSource` to listen to `LocalStorage` changes using the `settings://` pseudo-protocol in the URI (See examples below).
A property approach to easily update data within a template
```handlebars
{{! listen for HTTP API changes}}
<DataSource
@src="/nspace/dc/services"
as |source|>
{{#if source.error}}
Something went wrong!
{{/if}}
{{#if (not source.data)}}
Loading...
{{/if}}
{{! the value of items will change whenever the data changes}}
{{#each source.data as |item|}}
{{item.Name}} {{! < Prints the item name }}
{{/each}}
</DataSource>
```
Both approaches can be used in tandem.
DataSources can also be recursively nested for loading in series as opposed to in parallel. Nested DataSources will not start loading until the immediate parent has loaded (ie. it has data) as they are not placed into the DOM until this has happened. However, if a DataSource has started loading, and the immediate parent errors, the nested DataSource will stop receiving updates yet it and its properties will remain accessible within the DOM.