Skip to main content

useObservations

Use useObservations() to search health observations and map them to the SDK’s typed measurement data in a React component.

Before you use it​

Render the component below OvokProvider. The hook uses the client from that provider and is intended for client-side React components.

Inputs​

InputRequiredWhat it does
typesYesSelects the measurement categories to search and map.
patientIdNoRestricts the search to the specified patient.
period.startNoSets the lower date bound; observations at or after this date are included by the search.
period.endNoSets the upper date bound; observations at or before this date are included by the search.
idNoRestricts the FHIR search to an Observation ID.
groupByNoControls how related observations are grouped into one measurement.
timeToleranceMsNoSets the maximum timestamp difference for time grouping and the default unlinked-observation fallback; defaults to 1,000 ms.
countNoSets the FHIR search page size.
sortNoPasses a FHIR _sort expression to the search.
elementsNoSelects returned FHIR fields using _elements; accepts a comma-separated string or a list.

Both period bounds accept JavaScript Date values and can be used independently. The hook sends them as FHIR date filters (ge for start, le for end). When both are set, they are sent as two date query parameters (date=ge…&date=le…), not as one comma-separated value. If patientId, id, or a date bound is omitted, that filter is not applied; results may include all matching observations available to the configured client. count, sort, and elements are forwarded as FHIR search controls.

Measurement categories​

Use only categories with a documented observation mapping: bloodGlucose, bloodPressure, ecg, bloodOxygenPulseRate, bodyWeight, temperature, urineAnalysis, uricAcid, heartRate, heartRateVariability, respiratoryRate, vo2Max, stepCount, restingHeartRate, and walkingHeartRateAverage.

uricAcid is deprecated; use urineAnalysis for new work. Although the enum also declares symptomQuestionnaire, cosinussMultiParam, photoUpload, and spirometryPanel, those keys do not currently have a typed read mapping. Do not pass them to this hook and expect mapped measurements. See the measurement support matrix and the dedicated category pages.

Return value​

FieldMeaning
measurementsTyped measurement values mapped from the matching observations. The requested types narrow the measurement variants returned.
observationsThe original observation resources returned by the search, as a read-only list.
loadingWhether the search is still in progress.
errorAn Error when the search reports a failure; otherwise undefined.

When no observations match, measurements and observations are empty lists after loading completes. Use error to distinguish a failed search from a successful search with no results.

How results are grouped​

The hook derives observation-code filters from types, searches the matching observations, and then maps them into SDK measurement shapes. A single measurement can be represented by multiple observations, so the hook searches broadly enough to retrieve related observations before grouping them. Do not assume one returned observation always equals one returned measurement.

groupBy defaults to "hasMember", which groups resources connected through FHIR hasMember references and applies a time-based fallback to unlinked observations. Set it to "time" to group by nearby timestamps, or pass a callback that returns the group key for each observation. With time-based grouping, timeToleranceMs is the maximum distance from a group's first timestamp; the default is 1,000 milliseconds. A tolerance below zero is treated as zero. Observations without a usable timestamp cannot join a time-based group with another observation.

The original resources are available in observations, while measurements contains mapped values. The mapped array's measurement variants are narrowed by the literal categories passed in types. refetch() repeats the current search. It does not change the inputs or perform a server-side write.

The mapped measurements contain the values needed for the selected supported categories. Keep observations when the UI also needs original resource details that are not part of the mapped measurement shape.

Common patterns​

  • Use patientId when a screen is scoped to one patient.
  • Use one or both period bounds for a date-filtered view.
  • Use id when the view starts from a known Observation resource; use count, sort, and elements to control the underlying FHIR search.
  • Keep groupBy consistent with how the source system relates component observations. Prefer the default when resources use hasMember references.
  • Render loading, error, empty, and populated states separately.
  • Confirm that the selected measurement categories and device sources are available in the target Ovok environment. This hook maps data; it does not decide what a reading means clinically.

Example​

This component loads heart-rate measurements and keeps loading, failure, and empty states separate:

import { MeasurementTypeKey, useObservations } from '@ovok/core';

const heartRateTypes = [MeasurementTypeKey.heartRate] as const;

export function HeartRateList({ patientId }: { patientId?: string }) {
const { measurements, loading, error } = useObservations({
types: heartRateTypes,
patientId,
});

if (loading) return <p>Loading measurements…</p>;
if (error) return <p role="alert">{error.message}</p>;
if (measurements.length === 0) return <p>No heart-rate readings found.</p>;

return (
<ul>
{measurements.map((measurement, index) => (
<li key={index}>{measurement.heartRate ?? 'Value unavailable'}</li>
))}
</ul>
);
}