# Basic

## Introducing

API provides a set of functions for advanced work with the tree: add/remove tree node, searching, changing state and so on.

It is divided into 2 parts for several reasons:

* for reducing the weight of the component
* a separate API has more features that are not very often needed in the work

## Connection

The connection of the API is very easy. The component has a property `onReady`. It calls right after `componentDidMount` call. The API object is passed as the first argument to the `onReady` function.

```javascript
class AwesomeComponent extends React.PureComponent {
    treeApi = null
    
    handleTreeReady = (treeApi) => {
        this.treeApi = treeApi
    }
    
    render() {
        return <EyzyTree 
            data={data}
            onReady={this.handleTreeReady}
        />
    }
}
```

## Methods

{% hint style="info" %}
Most methods accept a **Query** argument. Full description: [Query](/tree/api/query.md)
{% endhint %}

### find

* **Description**: Finds nodes by specified [Query](/tree/api/query.md)
* **Arguments**:&#x20;
  * `query`: [Query](/tree/api/query.md)
* **Returns**:&#x20;
  * `TreeNode`
  * `null` if node is not found
* **Usage:**&#x20;

```javascript
const awesomeNode = this.treeApi.find({text: 'Awesome Node'})
```

###

### findAll

* **Description**: Similar to `find` method. But it returns all found nodes.
* **Arguments**:&#x20;
  * `query`: [Query](/tree/api/query.md)
* **Returns**:&#x20;
  * `Array<TreeNode>`
* **Usage:**&#x20;

```javascript
const expandedNodes = this.treeApi.findAll({expanded: true})
```

###

### selected

* **Description**: Returns selected nodes. Simple.
* **Returns**: Result can be different depends on mode (multiple or single). See [Component props](/tree/component-props.md#options)
  * **Single mode:** `TreeNode` or `null`
  * **Multiple mode:** array of `TreeNode`. It will be **always** an array.
* **Usage:**&#x20;

Single mode:

```javascript
const selectedNode = this.treeApi.selected()

this.setState({
    selectedNodeText: selectedNode ? selectedNode.text : 'Please select a node'
})
```

Multiple mode:&#x20;

{% hint style="info" %}
For a tree in multi-selection mode the **selected** method returns *always* an array. It does not matter if the selected nodes or not.
{% endhint %}

```jsx
<EyzyTree 
    data={data}
    multiple={true}
/>
```

```javascript
const selectedNodes = this.treeApi.selected()

this.setState({
    selectedNames: selectedNodes.map(node => node.text).join(', ')
})
```

###

### checked

* **Description**: For `checkable` mode the library will combine checked nodes into an array. There are different ways to select "checked" nodes by using `valueConsistsOf` argument.
  * `ALL` (default) it will gather all "checked" nodes
  * `BRANCH` if node has children and it is checked (and all of the children nodes are checked) then all children nodes will be excluded from the result
  * `LEAF` returns nodes which doesn't has children nodes
  * `WITH_INDETERMINATE` the same as `ALL`plus indeterminate nodes
* **Arguments**:&#x20;
  * `valueConsistsOf`: 'ALL' | 'BRANCH' | 'LEAF' | 'WITH\_INDETERMINATE'
  * `showDisabled`: boolean (default **false**)
* **Returns**:&#x20;
  * `Array<TreeNode>`
* **Usage:**&#x20;

```javascript
const checkedBranches = this.treeApi.checked('BRANCH')
```

###

### set

{% hint style="info" %}
It is not recommended to use this method.
{% endhint %}

* **Description**: Set any property to node. This method use `find` method from the API. So it will apply changes only for the **first** match.
* **Arguments**:&#x20;
  * `criteria` [Find criteria](/tree/api/query.md)
  * `propName`: node of a property (ex: expanded, disabled and so on)
  * `propValue`
* **Returns**:&#x20;
  * `boolean`
* **Usage:**&#x20;

```javascript
this.treeApi.set({expanded: false}, 'expanded', true)
```

To apply changes for all matches use next snippet:

```javascript
const checkedNodes = this.treeApi.findAll({checked: true})

checkedNodes.forEach(node => {
    this.treeApi.set(node.id, 'checked', true)
})
```

###

### data

{% hint style="info" %}
You can store here whatever you want.&#x20;
{% endhint %}

* **Description**: It is getter/setter for the `data` property of the node.
* **Arguments:**
  * `query`: [Query](/tree/api/query.md)
  * `key`: string | object
  * `value` : any (not required)
* **Returns:**&#x20;
  * `undefined`
  * `data object`
  * `TreeNode`
* **Usage:**

```jsx
// tree data
const data = [
    { text: 'Item 1', data: { isSuper: true } },
    { text: 'Item 2' },
    { text: 'Item 3' }
]

// it will find the first item (!)
this.treeApi.data(/Item/, 'isSuper', false)
// or
// data is instead extended by shallow merge
// node.data will be { isSuper: false, isSuper2: false }
this.treeApi.data(/Item/, { isSuper2: false })

```

{% hint style="info" %}
This method has different return results
{% endhint %}

```jsx
// tree data
const data = [
    { text: 'Item 1', data: { isSuper: true } },
    { text: 'Item 2' },
    { text: 'Item 3' }
]

// return a value: value
this.treeApi.data(/Item/, 'isSuper')

// get full data object: { isSuper: true, isSuper2: 'string' }
this.treeApi.data(/Item/)

// setter: return TreeNode
this.treeApi.data(/Item/, { isSuper2: false })

// setter: return TreeNode
this.treeApi.data(/Item/, 'isSuper2', 'string')
```

###

### addClass

* **Description**: It will add classNames for the node. This class will be added to the node with the class `.node-content` (check [Node's structure](/tree/customization.md#nodes-strcutrure))
* **Arguments:**
  * `query`: [Query](/tree/api/query.md)
  * `Array<className>`: string\[]
* **Returns:**&#x20;
  * `TreeNode` if node is found
  * `null` if node is not found
* **Usage:**

```javascript
this.treeApi.addClass(/excess/, ['excess-node', 'you-can', 'pass', 'many', 'names'])
```

###

### removeClass

* **Description**: The same behavior as `addClass` method, but it removes classNames
* **Arguments:**
  * `query`: [Query](/tree/api/query.md)
  * `Array<className>`: string\[]
* **Returns:**&#x20;
  * `TreeNode` if node is found
  * `null` if node is not found
* **Usage:**

```javascript
this.treeApi.removeClass(/excess/, ['excess-node', 'you-can', 'pass', 'many', 'names'])
```

###

### hasClass

* **Description**: Checks if a node has a `className`
* **Arguments:**
  * `query`: [Query](/tree/api/query.md)
  * `className`: string
* **Returns:**&#x20;
  * `boolean`
* **Usage:**

```javascript
const hasClass = this.treeApi.hasClass(/excess/, 'highligted')
```

###

### append

* **Description**: Inserts nodes to the end of the matched node
* **Arguments:**
  * `query`: [Query](/tree/api/query.md)
  * `nodes`: *string | object | Promise*
  * `opts`: [Insertion options](/tree/guides/async.md#insertion-options)
* **Returns:**&#x20;
  * `Promiselike<TreeNode[]>` added nodes (always an array)
  * `null` if node is not found
* **Usage:**

```javascript
const appendedNodes = this.treeApi.append(
    'Item 1', // find criteria
    ['Item 1.1.', 'Item 1.2'], // nodes can be as string
    true // expand node with text 'Item 1' (if node was found)
)

this.treeApi.append(
    { selected: true },
    [
        { text: 'Selected children 1', disabled: true },
        { text: 'Selected children 2' }        
    ]
)

// it also can be a function, but it must return a Promise
this.treeApi.append(
    'Selected children 2',
    (node) => {
        // node.text === 'Selected children 2'
        return fetch(`/api?childName=${node.text}`)
            .then(response => response.json())
    }
)
```

###

### prepend

* **Description**: This method is similar to `append`. But nodes inserting to the beginning of children list. (well ... you know, as well as jQuery :) )
* **Example:**

```javascript
// tree structure
/**
item 1
item 2
 item 2.1
 item 2.2
item 3
*/

this.treeApi.append('item 2', [
 'item 2.3', 'item 2.4', { text: 'item 2.5', checked: true }
])

// will be:
/**
item 1
 item 2.3    << new node
 item 2.4    << new node
 item 2.5    << new node
 item 2.1
 item 2.2
item 2
item 3
*/
```

###

### before

* **Description**: This method is similar to `append`. But nodes inserting **before** matched node.
* **Example:**

```javascript
// tree structure
/**
item 1
item 2
item 3
*/

this.treeApi.before(/item 2/, 'item n')

// will be:
/**
item 1
item n <<<<<<< -- added node
item 2
item 3
*/
```

###

### after

* **Description**: This method is similar to `append`. But nodes inserting **after** matched node.

```javascript
// tree structure
/**
item 1
item 2
item 3
*/

this.treeApi.before(/item 2/, 'item n')

// will be:
/**
item 1
item 2
item n <<<<<<< -- added node
item 3
*/
```

###

### remove

* **Description**: It removes matched node.
* **Arguments:**
  * `query`: [Query](/tree/api/query.md)
* **Returns:**&#x20;
  * `TreeNode` removed node
  * `null` if node is not found
* **Usage:**

```javascript
const removedNode = this.treeApi.remove(/bad node/)

if (removedNode) {
    alert(`Congrat... node(${removedNode.id} has removed!`)
}
```

###

### uncheckAll

* **Description**: Set for all *checked* nodes *unchecked* states

### unselectAll

* **Description**: Removes selection for all selected nodes

###

### toArray

* **Description**:  Returns list of nodes.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://eyzy.gitbook.io/tree/api/basic.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
