Custom DataSource: Editor refreshes Query without calling onRunQuery()

Hi,
I’m developing a custom datasource with a go backend. I have the wired problem that if I open the queryeditor the query is refreshed already when I call onChange(). I don’t have to call onRunQuery(). If I use the same QueryEditor in Explore everything is working as expected, but in the Edit Area the query is refreshed immediately…
You can find parts of my code below. If further information is required please let me know.
Would be great if someone can point me in the right direction…

In Edit Mode the Query is always refreshing:
edit_isrefreshing

in Explore Mode its working as expected: (Refresh onBlur of second field)
explorer_isnotrefreshing

 onVal = (event: ChangeEvent<HTMLInputElement>) => {
    const { onChange, query } = this.props;
    onChange({ ...query, queryMstsById: (event.currentTarget.value) });
  };
...
<InlineFieldRow>
              <InlineField tooltip="set the IDs you want to query in a comma seperated list" label="Messstellen IDs" labelWidth={26}>
                <Input
                  name="queryMstsById"
                  required
                  value={queryMstsById}
                  css=""
                  autoComplete="off"
                  width={40}
                  onChange={this.onVal}
                />
              </InlineField>
          </InlineFieldRow>

Where are you calling the onRunQuery? You mention that it’s run onBlur in Explore, but I don’t see it in your example?

Hi Marcus,
thanks for your reply. As you have noticed If have only snipped a part of my code. For testing proposes and to show the problem the onBlur Function is only called on the second Input Field.
You can find the corresponding code below:

QueryEditor.tsx:

import React, { ChangeEvent, PureComponent } from 'react';
import { Input, InlineSwitch, InlineField, InlineFieldRow } from '@grafana/ui';

import { QueryEditorProps } from '@grafana/data';
import { DataSource } from './datasource';
import { TebisDataSourceOptions, TebisQuery } from './types';

type Props = QueryEditorProps<DataSource, TebisQuery, TebisDataSourceOptions>;

export class QueryEditor extends PureComponent<Props> {

  onLiveStreamChange = (event: ChangeEvent<HTMLInputElement>) => {
    const { onChange, query } = this.props;
    onChange({ ...query, queryStream: (event.target.checked) });
  };

  onVal = (event: ChangeEvent<HTMLInputElement>) => {
    const { onChange, query } = this.props;
    onChange({ ...query, queryMstsById: (event.currentTarget.value) });
  };

  onRateChange = (event: ChangeEvent<HTMLInputElement>) => {
    const { onChange, query } = this.props;
    onChange({ ...query, queryRate: (event.currentTarget.value) });

  };

  onBlur = (event: ChangeEvent<HTMLInputElement>) => {
    const { onRunQuery } = this.props;
    onRunQuery();
  }

  render() {
    const { queryMstsById, queryRate, queryStream } = this.props.query;
    return (
      <div>
        <InlineFieldRow>
          <InlineField tooltip="set the IDs you want to query in a comma seperated list" label="Messstellen IDs" labelWidth={26}>
            <Input
              name="queryMstsById"
              required
              value={queryMstsById}
              css=""
              autoComplete="off"
              width={40}
              onChange={this.onVal}
            />
          </InlineField>
        </InlineFieldRow>
        <InlineFieldRow>
          <InlineField tooltip="set the Rate you want to query use an empty field or -1 to let the system choose the best rate" label="Rate" labelWidth={26}>
            <Input
              name="queryRate"
              required
              value={queryRate}
              css=""
              autoComplete="off"
              width={40}
              onChange={this.onRateChange}
              onBlur={this.onBlur}
            />
          </InlineField>
        </InlineFieldRow>
        <InlineFieldRow>
          <InlineField tooltip="if this is enabled the query will be streamed if timerange depends on 'now'" label="Live-Streaming" labelWidth={26}>
            <InlineSwitch
              name="queryStream"
              required
              value={queryStream ?? false}
              css=""
              autoComplete="off"
              onChange={this.onLiveStreamChange}
            />
          </InlineField>
        </InlineFieldRow>
      </div>
    );
  }
}

the onChange function is like that:

export const handlerFactory =
  (original: object, onChange: (copy: any) => void) =>
  (path: string, format: (value: string) => string | number | boolean | null = (value) => value) =>
  (event: ChangeEvent<HTMLInputElement>): void => {
    const copy = _.cloneDeep(original);
    onChange(_.set(copy, path, format(event.currentTarget.value)));
  };