# Query

### Introdution

Due to the nature of the React, we cannot save a link to the node, because after each operation the link will be lost. We may also often need to dynamically do something with the node.

There are simple but powerful sets of rules for searching. In the basic API, almost all methods use these rules as the first argument in order to understand to which particular node to apply a specific action.

The simpliest example:

```javascript
const favouriteNode = this.api.find('Favourite one')
```

The code above will try to find node that text equals to **"Favourite one".** Recieved argument will be transformed to:

```javascript
const query = { text: 'Favourite one' }
```

### Query variants:

* Pass string. It is synthetic sugar to `{ text: "Favourite one' }`

```javascript
this.api.find('Favourite one') // => { text: 'Favourite one' }
```

* Pass string (as **id).** Also it can be an id. It will automatically search by **text** or **id** at the same time.

```javascript
this.api.find('myNodeId') // => { id: 'myNodeId' }
this.api.find({ id: /my_id/ }) // as RegExp
```

* Pass RegExp object. It also searching by node **text** or **id.**

```javascript
this.api.find(/Favorite/i) // => { text: /Favourite/i }
```

* Pass object. It will compare by keys and check whether its values are equals.&#x20;

{% hint style="info" %}
List of defined values:

* expandable
* expanded
* disabledCheckbox
* disabled
* checkable
* checked
* selected
  {% endhint %}

```javascript
this.api.find({
    selected: true,
    // disabled: false,
    // expanded: true
    // and so on
})
```

Good example to find all expanded node (or vice versa). In the example we using `findAll` method. This method use the same rules as described on this page.

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

// collapse all expanded nodes
expandedNodes.forEach(node => this.api.set(node, 'expanded', false))
```

It's possible to pass custom property:

```javascript
this.api.findAll({
    mySuperProperty: true
})
```

* Pass nested keys.&#x20;

```javascript
this.api.find({
    'data.signature': /owner/
})

// Yeah, it also possible. 
// will try to find a node whose text of the second child is “Some child”
this.api.find({
    'child.1.text': 'Some Child'
})
```

* Pass special keys.&#x20;

```javascript
// node which doesn't has a children
this.api.find({
    'isLeaf': true
})

// it's vice versa of { selected: true }
// or equal { selected: false }
this.api.find({
    $not: {
        selected: true
    }
})
```

* Pass function

```javascript
// node which doesn't has a children
this.api.find(node => {
    return node.mySuperProperty >= 100
})
```

###

### Logical Query Operators

* **or**

You just need to pass the above rules to the array.

```javascript
this.api.find(['Item 1', 'Item 2'])

this.api.find([
    { text: /item \d{2}\-n/, checked: true },
    { text: /subitem \d{2}\-n/, checked: true }
])
```

* **and**

```javascript
this.api.find({
    'data.weight': 100,
    'text': /item/,
    'selected': true
})
```
