Interface: TreeDataProvider

Oracle® JavaScript Extension Toolkit (JET)
17.1.0

G12196-01

Since:
  • 5.1.0
Module:
  • ojtreedataprovider

QuickNav

Description

TreeDataProvider is the basic interface for getting runtime data which JET components that display hierarchical list of items (such as oj-tree-view) can use.

This interface extends DataProvider, with the addition of a getChildDataProvider method.

Unless otherwise noted, all methods operate on the set of sibling items with the same parent. For example, fetchFirst returns an iterable for the sibling items with the same parent; getTotalSize returns a promise that resolves to the number of items with the same parent.

To retrieve the children of an item, consumers use the getChildDataProvider method to get another TreeDataProvider for the children of that item.

JET provides some implementations of this interface, such as ArrayTreeDataProvider and RESTTreeDataProvider.

Applications can also create their own implementations of this interface and use them with JET components that support it. For example, an application can create a TreeDataProvider implementation that fetches data from a REST endpoint.

Implementation class must implement all of the interface methods. It should also fire the events described below when appropriate, so that JET components or other consumers can respond to data change accordingly.

Events

Implementation can fire the following events by creating an instance of the event class and passing the event payload in the constructor. All events should be fired at the root-level TreeDataProvider instance, so that consumers only need to add one listener for the entire tree. Events should not be fired at child-level TreeDataProvider returned by getChildDataProvider, as there is no bubbling support for DataProvider events.

DataProviderMutationEvent

This event is fired when items have been added, removed, or updated from the data. Items have been updated including their children changed.

Event payload is found under event.detail, which implements the DataProviderMutationEventDetail interface.

Consumers can add an event listener for the "mutate" event type on the DataProvider object.

DataProviderRefreshEvent

This event is fired when the data or subtree data has been refreshed and components need to re-fetch the data.

Event payload is found under event.detail, which implements the DataProviderRefreshEventDetail interface.

If this event contains no additional event payload, the re-fetch is from the root.

If this event contains 'keys', the re-fetch should be from each key.

Consumers can add an event listener for the "refresh" event type on the DataProvider object.

Example of implementation firing an DataProviderMutationEvent for removed items:
var removeDetail = {data: removedDataArray,
                    indexes: removedIndexArray,
                    keys: removedKeySet,
                    metadata: removedMetadataArray};
this.dispatchEvent(new DataProviderMutationEvent({remove: removeDetail}));
Example of consumer listening for the "mutate" event type:
var listener = function(event) {
  if (event.detail.remove) {
    var removeDetail = event.detail.remove;
    // Handle removed items
  }
};
dataProvider.addEventListener("mutate", listener);

Filtering

If the TreeDataProvider instance returns a FetchCapability object when getCapability() is called for capabilityName "filter" then filtering is defined. Note that it is up to the TreeDataProvider implementation to define the exact behavior of filtering and whether the DataProvider instances returned by getChildDataProvider() define filtering as well. For example, filtering may only be defined at the root TreeDataProvider and the DataProviders returned by getChildDataProvider() would already be filtered. Or filtering may be defined the lower levels which indicates that they can be filtered. It is expected that in most cases the filterCriterion will be applied to leaf nodes of the TreeDataProvider.


Usage

Signature:

interface TreeDataProvider<K, D> extends DataProvider<K, D>

Generic Parameters
ParameterDescription
KType of Key
DType of Data
Typescript Import Format
//To use this interface, import as below.
import TreeDataProvider= require("ojs/ojtreedataprovider");

//To access this interface in your code:
declare class MyTreeDataProvider implements TreeDataProvider

For additional information visit:


Methods

addEventListener(eventType: string, listener: EventListener): void

Add a callback function to listen for a specific event type.
Parameters:
Name Type Description
eventType string The event type to listen for.
listener EventListener The callback function that receives the event notification.

containsKeys(parameters : FetchByKeysParameters<K>) : Promise<ContainsKeysResults<K>>

Check if there are rows containing the specified keys. If this method is called on a DataProvider returned from getChildDataProvider(key), the rows will be only those from the children of the key.
Parameters:
Name Type Description
parameters FetchByKeysParameters contains by key parameters
Since:
  • 4.2.0
Returns:

Returns Promise which resolves to ContainsKeysResults.

Type
Promise.<ContainsKeysResults>
Example

Check if keys 1001 and 556 are contained

let containsKeys = [1001, 556];
let value = await dataprovider.containsKeys({keys: containsKeys});
let results = value['results'];
if (results.has(1001)) {
  console.log('Has key 1001');
} else if (results.has(556){
  console.log('Has key 556');
}

createOptimizedKeyMap(initialMap?: Map<K, D>): Map<K, D>

Return an empty Map which is optimized to store key value pairs

Optionally provided by certain DataProvider implementations for storing key/value pairs from the DataProvider in a performant fashion. Sometimes components will need to temporarily store a Map of keys provided by the DataProvider, for example, in the case of maintaining a Map of selected keys. Only the DataProvider is aware of the internal structure of keys such as whether they are primitives, Strings, or objects and how to do identity comparisons. Therefore, the DataProvider can optionally provide a Map implementation which can performantly store key/value pairs surfaced by the DataProvider.

Parameters:
Name Type Argument Description
initialMap Map.<any> <optional>
Optionally specify an initial map of key/values for the Map. If not specified, then return an empty Map.
Since:
  • 6.2.0
Returns:

Returns a Map optimized for handling keys from the DataProvider.

Type
Map.<any>
Example

create empty key Map

let keyMap = dataprovider.createOptimizedKeyMap();

createOptimizedKeySet(initialSet?: Set<K>): Set<K>

Return an empty Set which is optimized to store keys

Optionally provided by certain DataProvider implementations for storing keys from the DataProvider in a performant fashion. Sometimes components will need to temporarily store a Set of keys provided by the DataProvider, for example, in the case of maintaining a Set of selected keys. Only the DataProvider is aware of the internal structure of keys such as whether they are primitives, Strings, or objects and how to do identity comparisons. Therefore, the DataProvider can optionally provide a Set implementation which can performantly store keys surfaced by the DataProvider.

Parameters:
Name Type Argument Description
initialSet Set.<any> <optional>
Optionally specify an initial set of keys for the Set. If not specified, then return an empty Set.
Since:
  • 6.2.0
Returns:

Returns a Set optimized for handling keys from the DataProvider.

Type
Set.<any>
Example

create empty key Set

let keySet = dataprovider.createOptimizedKeySet();

dispatchEvent(evt: Event): boolean

Dispatch an event and invoke any registered listeners.
Parameters:
Name Type Description
event Event The event object to dispatch.
Returns:

Return false if a registered listener has cancelled the event. Return true otherwise.

Type
boolean

fetchByKeys(parameters : FetchByKeysParameters<K>) : Promise<FetchByKeysResults<K, D>>

Fetch rows by keys. If this method is called on a DataProvider returned from getChildDataProvider(key), the rows will be only those from the children of the key.
Parameters:
Name Type Description
parameters FetchByKeysParameters fetch by key parameters
Since:
  • 4.2.0
Returns:

Returns Promise which resolves to FetchByKeysResults.

Type
Promise.<FetchByKeysResults>
Example

Fetch for keys 1001 and 556

let fetchKeys = [1001, 556];
let value = await dataprovider.fetchByKeys({keys: fetchKeys});
// get the data for key 1001
console.log(value.results.get(1001).data);

fetchByOffset(parameters: FetchByOffsetParameters<D>): Promise<FetchByOffsetResults<K, D>>

Fetch rows by offset

A generic implementation of this method is available from FetchByOffsetMixin. It is for convenience and may not provide the most efficient implementation for your data provider. Classes that implement the DataProvider interface are encouraged to provide a more efficient implementation.

Parameters:
Name Type Description
parameters FetchByOffsetParameters fetch by offset parameters
Since:
  • 4.2.0
Returns:

Returns Promise which resolves to FetchByOffsetResults.

Type
Promise.<FetchByOffsetResults>
Example

Fetch by offset 5 rows starting at index 2

let result = await dataprovider.fetchByOffset({size: 5, offset: 2});
let results = result['results'];
let data = results.map(function(value) {
  return value['data'];
});
let keys = results.map(function(value) {
  return value['metadata']['key'];
});

fetchFirst(parameters?: FetchListParameters<D>): AsyncIterable<FetchListResult<K, D>>

Get an AsyncIterable object for iterating the data.

AsyncIterable contains a Symbol.asyncIterator method that returns an AsyncIterator. AsyncIterator contains a “next” method for fetching the next block of data.

The "next" method returns a promise that resolves to an object, which contains a "value" property for the data and a "done" property that is set to true when there is no more data to be fetched. The "done" property should be set to true only if there is no "value" in the result. Note that "done" only reflects whether the iterator is done at the time "next" is called. Future calls to "next" may or may not return more rows for a mutable data source.

In order for JET components to work correctly, DataProvider implementations should ensure that:

  • The iterator accounts for data mutations when returning the next block of data, and that no row is duplicated or skipped. For example, an offset-based implementation may need to adjust the offset from which the next block of data starts if rows have been added or removed in the returned data.
  • JET components may call "next" on the iterator even after the iterator has returned done:true. If new data is available after the last returned row, the iterator is expected to return the new data and set "done" to false. This differs from the AsyncIterator spec for performance reasons.

Please see the DataProvider documentation for more information on custom implementations.

Parameters:
Name Type Argument Description
params FetchListParameters <optional>
fetch parameters
Since:
  • 4.2.0
See:
Returns:

AsyncIterable with FetchListResult

Type
AsyncIterable.<FetchListResult>
Example

Get an asyncIterator and then fetch first block of data by executing next() on the iterator. Subsequent blocks can be fetched by executing next() again.

let asyncIterator = dataprovider.fetchFirst(options)[Symbol.asyncIterator]();
let result = await asyncIterator.next();
let value = result.value;
let data = value.data;
let keys = value.metadata.map(function(val) {
  return val.key;
});

getCapability(capabilityName: string): any

Determines whether this DataProvider defines a certain feature.
Parameters:
Name Type Description
capabilityName string capability name. Defined capability names are: "fetchByKeys", "fetchByOffset", "sort", "fetchCapability" and "filter".
Since:
  • 4.2.0
Returns:

capability information or null if undefined

Type
Object
Example

Check what kind of fetchByKeys is defined.

let capabilityInfo = dataprovider.getCapability('fetchByKeys');
if (capabilityInfo.implementation == 'iteration') {
  // the DataProvider supports iteration for fetchByKeys
  ...

getChildDataProvider(key: K): TreeDataProvider<K, D> | null

Get the data provider for the children of the row identified by key.
Parameters:
Name Type Description
key any key of the row to get child data provider for.
Since:
  • 5.1.0
Returns:

A TreeDataProvider if the row can (but doesn't have to) have children; or null if the row cannot have children. Use the isEmpty method on the returned TreeDataProvider to determine if it currently has children.

Type
TreeDataProvider | null

getTotalSize : {Promise.<number>}

Return the total number of rows in this dataprovider
Returns:

Returns a Promise which resolves to the total number of rows. -1 is unknown row count.

Type
Promise.<number>
Example

Get the total rows

let value = await dataprovider.getTotalSize();
if (value == -1) {
  // we don't know the total row count
} else {
  // the total count
  console.log(value);
}

isEmpty(): 'yes' | 'no' | 'unknown'

Returns a string that indicates if this data provider is empty. Valid values are:
  • "yes": this data provider is empty.
  • "no": this data provider is not empty.
  • "unknown": it is not known if this data provider is empty until a fetch is made.
Since:
  • 4.2.0
Returns:

string that indicates if this data provider is empty

Type
"yes" | "no" | "unknown"
Example

Check if empty

let isEmpty = dataprovider.isEmpty();
console.log('DataProvider is empty: ' + isEmpty);

removeEventListener(eventType: string, listener: EventListener): void

Remove a listener previously registered with addEventListener.
Parameters:
Name Type Description
eventType string The event type that the listener was registered for.
listener EventListener The callback function that was registered.