Custom visualization request handler cannot read Timefilter?

I'm trying to write a custom request handler for retrieving the index source from ES. I have found an example from this plugin here that I am trying to copy. I have tried cloning this plugin and running it in order to debug it and understand how it works, but when I try to create the visualisation I get the following error:

TypeError: Cannot read property 'from' of undefined

on this line: 'gte': timeFilter.from,

I am trying to run this under kibana 6.5.4, but I am unsure if this plugin may be outdated and simply not using the correct attributes anymore. Can anyone help with this error? This full source code is below:

const getRequestBody = (params, queryFilter, timeFilter) => {
  const requestBody = {
    'size': 0,
    'query': {
      'bool': {
        'must': [
          {
            'range': {
              'timestamp': {
                'gte': timeFilter.from,
                'lte': timeFilter.to
              }
            }
          }
        ]
      }
    },
    'aggs': {
      'sessions': {
        'terms': {
          'field': params.sessionField,
          'size': params.maxSessionCount
        },
        'aggs': {
          'first_events': {
            'top_hits': {
              'sort': [
                {
                  [params.timeField]: {
                    'order': 'asc'
                  }
                }
              ],
              '_source': {
                'includes': [params.actionField]
              },
              'size': params.maxSessionLength
            }
          }
        }
      }
    }
  };
  const queries = queryFilter.getFilters();
  if (queries && queries.length) {
    queries.forEach(({ meta }) => {
      if (meta.disabled) return;
      let query;
      switch (meta.type) {
        case 'phrase':
          query = {
            match: {
              [meta.key]: meta.value
            }
          };
          addMustQuery(requestBody, query, meta);
          break;
        case 'phrases':
          meta.params.forEach(param => {
            query = {
              match: {
                [meta.key]: param
              }
            };
            addShouldQuery(requestBody, query, meta);
          });
          break;
        case 'range':
          query = {
            range: {
              [meta.key]: meta.params
            }
          };
          addRangeQuery(requestBody, query, meta);
          break;
        case 'exists':
          query = {
            exists: {
              field: meta.key
            }
          };
          addMustQuery(requestBody, query, meta);
      }
    });
  }
  return requestBody;
};

function addMustQuery(request, query, { negate }) {
  const boolObject = request.query.bool;
  let matcher;
  if (negate) {
    matcher = boolObject.must_not ? boolObject.must_not : (boolObject.must_not = []);
  } else {
    matcher = boolObject.must ? boolObject.must : (boolObject.must = []);
  }
  matcher.push(query);
}

function addShouldQuery(request, query, { negate }) {
  let matcher;
  if (negate) {
    matcher = request.query.bool.must_not ? request.query.bool.must_not : (request.query.bool.must_not = []);
  } else {
    matcher = request.query.bool.should ? request.query.bool.should : (request.query.bool.should = []);
    request.query.bool.minimum_should_match = 1;
  }
  matcher.push(query);
}

function addRangeQuery(request, query, { negate }) {
  let matcher;
  if (negate) {
    matcher = request.query.bool.must_not ? request.query.bool.must_not : (request.query.bool.must_not = []);
  } else {
    matcher = request.query.bool.must;
  }
  matcher.push(query);
}

export function RequestHandlerProvider(Private, es) {
  return {
    handle(vis) {
      const { timeFilter, queryFilter } = vis.API;
      return new Promise(resolve => {
        const params = vis.params;
        const requestBody = getRequestBody(params, queryFilter, timeFilter.time);
        es.search({
          index: 'analytics',
          body: requestBody
        }).then(result => resolve(result));
      });
    }
  };
}

I have found this blog post that says access to Timefilter was removed as of Kibana 6.4, but the page doesn't give any good examples of how to access now, at least to someone who is unfamiliar with it.

I tried accessing the from and to values using timeFilter.time.to etc. but this also fails with the same error as above

I found the solution to this. The issue was that the Timefilter.js for 6.5 changed from using time to _time. This means that I had to update line const requestBody = getRequestBody(params, queryFilter, timeFilter.time) to be const requestBody = getRequestBody(params, queryFilter, timeFilter._time), which resolved the issue.

Thanks for posting the solution!

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.