How to use getBackendSrv().fetch()?

How to make the getBackendSrv function from the @grafana/runtime packages to deploy successfully based on Grafana’s tutorial “Build a Data Source Plugin.”

  • What Grafana version and what operating system are you using?

    • Grafana: V8.1.4
    • OS: Windows 10
  • What are you trying to achieve?

    • I am trying to fetch the data from http and push the data onto Grafana Dashboard for visualization.
  • How are you trying to achieve it?

    • I am using @grafana/toolkit package and following the tutorial from Grafana’s “Build a Data Source Plugin” section, “Get data from an external API,” to pull and push the data from external source (http) onto Grafana Dashboard. Build a data source plugin | Grafana documentation
  • What happened?

    • There is no error thrown from packaging and deploying the package and datasource.ts when using yarn dev command but nothing was shown from the dashboard and the red exclamation mark said “failed to fetch.”

import {
  DataQueryRequest,
  DataQueryResponse,
  DataSourceApi,
  DataSourceInstanceSettings,
  MutableDataFrame,
  FieldType,
} from '@grafana/data';

// Grafana tool
import { getBackendSrv } from "@grafana/runtime";

// import { MyQuery, MyDataSourceOptions, defaultQuery } from './types';
import { MyQuery, MyDataSourceOptions } from './types';

export class DataSource extends DataSourceApi<MyQuery, MyDataSourceOptions> {
  constructor(instanceSettings: DataSourceInstanceSettings<MyDataSourceOptions>) {
    super(instanceSettings);
  }
  async doRequest(query: MyQuery) {
    const result = await getBackendSrv().datasourceRequest({
      method: "GET",
      // the link shown below is made up & will not work but a legit http link is used for this
      url: "http://demo.api.com/",
      params: query,
    })
    return result;
  }

  async query(options: DataQueryRequest<MyQuery>): Promise<DataQueryResponse> {
    const promises = options.targets.map((query) =>
      this.doRequest(query).then((response) => {
        const frame = new MutableDataFrame({
          refId: query.refId,
          fields: [
            // { name: "company", values: response.data.status, type: FieldType.number }
            { name: "company", type: FieldType.string },
            { name: "currentPrice", type: FieldType.number },
          ],
        });

        response.data.forEach((point: any) => {
          frame.appendRow([point]);
        });
        return frame;
      })
    );
    return Promise.all(promises).then((data) => ({ data }));
  }

I have tried to work around this by using axios and node-fetch packages but it does not work as well. I am suspecting that I am missing some key elements here that has caused the data not to return properly. The http link that I used to fetch data from the web, works perfectly in both JS and TS but does not work well when packaging with @grafana/toolkit package.

I also spot a deprecated message when following this Grafana tutorial using vscode where it says use fetch method instead. Hence, I would also like to know if there are any tutorials that I can follow for using fetch method with @grafana/toolkit package.

  • What did you expect to happen?

    • I was expecting the data to feed into Grafana dashboard similarly to the previous tutorial where we have a table of data for visualization on Grafana dashboard, the sine wave, see below.

  • Can you copy/paste the configuration(s) that you are having problems with?

    • N/A
  • Did you receive any errors in the Grafana UI or in related logs? If so, please tell us exactly what they were.

    • I received an unexpected error from Grafana UI but I could not troubleshoot it successfully from multiple attempts. I am suspecting that the module.ts does not fetch any data from the http link given, but I think it should because a stand alone JS and TS scripts can fetch the data successfully.
// From Grafana UI
Unexpected error
----------------
TypeError
  data: Object
    message: "Unexpected error"

Any suggestions and guidance will be truly appreciated. I just need to fetch the data from http and push it onto Grafana dashboard as a Grafana data source plugin. Thanks in advance.

Hey guys,

I am able to resolve this by allowing the cross domain requests from browsers from our backend side by setting header “Access-Control-Allow-Origin.”

See below for reference:

However, I am utilizing the deprecated datasourceRequest method for fetching and calling the data onto Grafana dashboard. I am hoping to see more documents and tutorials in the future in regard to using the fetch method from getBackendSrv to pull the data.

Feel free to close it.

Thanks & Best.

The main difference from datasourceRequest is that fetch returns a RxJS stream rather than a Promise. You can however convert it back using the toPromise() method.

Here’s an example of how to use fetch:

2 Likes

For anyone who drops in here from a search engine, I’ve posted a longer answer to how to use fetch here:

2 Likes

Thank you @marcusolsson. This is super helpful :grin:

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