javascriptreactjskeen-io

calling this.setState() inside keen client.query.then() returns cannot read property setState


I have a keen extraction query setup inside my react component. When I render the keen query results inside keen's table it works fine.
The problem occurs when I try to store the query results inside the state and try to render that data in a custom data table.


Below is the code of my keen query:

Keen.ready(function () {
  const element = document.getElementById('keen-table-chart');
  const chart = new Keen.Dataviz()
    .el(element)
    .type('table')
    .height(400)
    .prepare();
  client
    .query('extraction', {
      event_collection: 'Arrivy Datastore',
      timeframe: 'this_30_days',
      timezone: 18000,
      filters: filtersArray,
      property_names: propertyNames
    })
    .then(res => {
      this.setState({
        queryResults: res
      }, () => { this.renderDataTable(res); });
    })
    .catch(err => {
      chart
        .message(err.message);
    });
});

this.setState in the .then() returns Cannot read property 'setState' of undefined.


Solution

  • It seems like your are out of the component-context. This is due to your function-call in the first line, which removes the this-context.

    You will need to use bind or an arrow function. Since your are already using arrow functions, the code could like this.

    Keen.ready(() => {
      const element = document.getElementById('keen-table-chart');
      const chart = new Keen.Dataviz()
        .el(element)
        .type('table')
        .height(400)
        .prepare();
      client
        .query('extraction', {
          event_collection: 'Arrivy Datastore',
          timeframe: 'this_30_days',
          timezone: 18000,
          filters: filtersArray,
          property_names: propertyNames
        })
        .then(res => {
          this.setState({
            queryResults: res
          }, () => { this.renderDataTable(res); });
        })
        .catch(err => {
          chart
            .message(err.message);
        });
    });