DHIS2 Application Runtime Fetching

React hook

The hard part of fetching data is defining the data queries. Once those are defined we can use the library provided useDataQuery hook to execute the queries and get data back.

Hook parameters

useDataQuery has one mandatory parameter, the data query, and an optional second parameter where we can customize the behavior.

The second parameter, options, is expected to be an object.

  • variables: This property decides which variables are passed to the dynamic portions of the data query and must have an object type.
  • onComplete: This property can be used to specify a callback function to be called on successfull completion of the query. The function is called with the response data as the only argument.
  • onError: This property can be used to specify a callback function to be called on failure of the query. The function is called with the error instance as the only argument.
  • lazy: This property can be used make a query lazy in the sense that we have to call refetch before it makes it request. This property is false by default.

Hook results

useDataQuery returns an object from which we can extract many useful values.

  • called: This value is true if the hook has requested data from the server at least once.
  • loading: This value is true if the server has yet to respond. When a response is received or an error occurs, this value changes to false.
  • error: This value is undefined if no error has occured and the Error if one was thrown.
  • data: This value undefined if the data is loading or an error has occurred, otherwise a map from the name of each query definiton defined in the data query to the resulting data for that query.
  • refetch: This value is a function that can be called to refetch the data. Any in-flight HTTP requests will automatically be aborted.
  • engine: This value holds a reference to the DataEngine instance.

Importing

To use the data query hook we have to import it from the library first.

import { useDataQuery } from '@dhis2/app-runtime'

Code example: single resource query

Below we have defined a component that uses the useDataQuery hook and passes it a query with a single query definition.

import React from "react"
import { useDataQuery } from "@dhis2/app-runtime"
const query = {
programs: {
resource: "programs",
params: {
fields: "displayName",
},
}
}
const SomeComponent => (props) => {
const { loading, error, data } = useDataQuery(query)
return (
<div>
<h3>Programs</h3>
{loading && <span>...</span>}
{error && <span>{`ERROR: ${error.message}`}</span>}
{data && (
<pre>
{data.programs.programs
.map(program => program.displayName)
.join("\n")}
</pre>
)}
</div>
)
}
export { SomeComonent }

Code example: single resource dynamic identifier query

Below we have defined a component that uses the useDataQuery hook, passes it a query with a single query definition and also specifies the specific instance of the collection it's interested in.

import React from "react"
import { useDataQuery } from "@dhis2/app-runtime"
const query = {
program: {
resource: "programs",
id: ({ id }) => id,
params: {
fields: "displayName",
},
}
}
const SomeComponent => (props) => {
const { loading, error, data } = useDataQuery(query, {
variables: {
id: "abc",
}
})
return (
<div>
<h3>Specific program</h3>
{loading && <span>...</span>}
{error && <span>{`ERROR: ${error.message}`}</span>}
{data && (
<pre>
{data.program.displayName}
</pre>
)}
</div>
)
}
export { SomeComonent }

Code example: single resource dynamic parameters query

Below we have defined a component that uses the useDataQuery hook, passes it a query with a single query definition and also specifies custom values for the parameters.

import React from "react"
import { useDataQuery } from "@dhis2/app-runtime"
const query = {
orgUnits: {
resource: "organisationUnits",
params: ({ level }) => ({
fields: ["id", "displayName"],
filter: `level:eq:${level}`,
paging: false,
})
}
}
const SomeComponent => (props) => {
const { loading, error, data } = useDataQuery(query, {
variables: {
level: 2,
}
})
return (
<div>
<h3>Organisation Units (level 2)</h3>
{loading && <span>...</span>}
{error && <span>{`ERROR: ${error.message}`}</span>}
{data && (
<pre>
{data.orgUnits.organisationUnits
.map(ou => ou.displayName)
.join("\n")}
</pre>
)}
</div>
)
}
export { SomeComonent }