> For the complete documentation index, see [llms.txt](https://docs.wirebootstrap.com/wirebootstrap/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.wirebootstrap.com/wirebootstrap/executing-queries.md).

# Executing Queries

The simplest way to execute a query inside a dataset is using the `execAsync` method on the dataset.  This is the same method that is available on the [DataSource](/wirebootstrap/reference/wire.data/wire.data.datasource.md) class.

```typescript
const dataset = new wire.data.DataSet({
    Source: new wire.data.DataSource("custom", {
        ServiceRoot: "./account"
    }),
    Query: wire.data.select().from("Users")
});

const data = dataset.execAsync().done((data) => {
    // 'data' will contain the results of the query
});
```

## Data Promises

One difference between methods on the dataset and methods on the data source is that the data set methods return an instance of [wire.data.DataPromise](/wirebootstrap/reference/wire.data/wire.data.datapromise.md) instead of a [deferred jQuery promise](https://api.jquery.com/deferred.promise).

Depending on the method used, the dataset will put the promise it returns into a stack of promises to be updated when it picks up changes to its query and refreshes its data from the data service. &#x20;

The `execAsync` method does return a data promise but it does not add the promise to the internal stack of promises that receive updates when data changes.  This is a one-time request much like the behavior of the same method on the data source.

To get a data promise that is updated when data changes, use `execAsyncListen`.  This method will return a new data promise and add it to the update stack. &#x20;

```typescript
const dataset = new wire.data.DataSet({
    Source: new wire.data.DataSource("custom", {
        ServiceRoot: "./account"
    }),
    Query: wire.data.select().from("Users")
});

dataset.execAsyncListen().done((data) => {
    // 'data' will contain the results of the query
    // This will be called if any changes to the query in the dataset 
    //  are detected and new data becomes available
});
```

{% hint style="info" %}
Note, do not use this method unless you want the updates.  Calling this method over and over for one-time query requests will unnecessarily build up a stack of updates that are sent out when not needed.  This method is mainly used by presentation components that want updates so they can refresh their UI.
{% endhint %}

## Promise Callbacks

A data promise contains the same callbacks as a jQuery promise but adds an addition method to let consumers know when data is being refreshed in the data service.  This allows them to provide feedback such as a spinning icon in a presentation component. &#x20;

```javascript
...

dataset.execAsyncListen()
    .done((table) => {
        // initial or new data avaialble
    })
    .processing(() => {
        // dataset going to the data service for data
    })
    .fail((ex) => {
        // service request failed
    });
```

## DataTable Results

Another difference between the *exec* methods on the dataset vs the same ones on the data source is that data returned to the caller using a data set is a [DataTable](/wirebootstrap/reference/wire.data/wire.data.datatable.md) by default.

Notice in the example above, the object returned in the `done` callback is named a table for this reason.  This can be turned off using an optional configuration setting passed into any of the data set methods. &#x20;

In the example below, the result set is not cast into a data table and stays in its native format by using the `cast` option on the configuration parameter.

```javascript
...

const config = { cast: false };

dataset.execAsyncListen(config).done((data) => {
    // 'data' will be in whatever format was 
    // returned from the data service
});
```

## Refreshing Data

Use the data set `refresh` method to force a dataset to go back to the data service for new data and then update its promises letting consumers know about the change.  This method does not return a new promise.

This method is most used when the dataset's query is updated manually through code.  Here, the data set needs to be refreshed manually instead of via a data event listener.

```javascript
...

//
// Add a where clause to the requst for Users from the previous examples
//
dataset.Query.where().eq("Active", true);

//
// This will force a refresh of the data per the new query 
// and notify any consumers using the dataset
// waiting for updates via their data promises
//
dataset.refresh();
```

## Response Data

As seen in the examples above, the data returned from data service queries is available in the `done` callback of a data promise.  In addition, the data is also stored inside the dataset and can be accessed anytime via the `data` method on the dataset.

```javascript
const users = dataset.data();
```

For TypeScript applications, a helper method on the data set called `table` is defined in the WireBootstrap typings file as returning an `IDataTable` object for auto-casting into a [DataTable](/wirebootstrap/reference/wire.data/wire.data.datatable.md) in TypeScript.  This is helpful if the default data table casting behavior is not turned off.

```javascript
//
// This method is defined as returning an IDataTable object
//
let usersTable = dataset.table();

//
// We can now jump right into coding locally with 
// the strongly typed DataTable object
//
const jamie: User = usersTable.where().eq("UserName", "jkratz").first();
```

For more on executing queries in data sets, visit the [DataSet](/wirebootstrap/reference/wire.data/wire.data.dataset.md) reference page.  For more on data tables, visit the [DataTables](/wirebootstrap/reference/wire.data/wire.data.datatable.md) reference page.
