Working with object references
Compare, key, narrow, and print ObjRef values with areObjRefsEqual, serializeObjRef, and the type guards instead of reading identifier fields by hand.
An ObjRef points to one object in a workspace: a display form, a measure, a dataset, a dashboard. Every filter, attribute, measure, and widget the SDK hands you carries one. This page lists the helpers for comparing, keying, narrowing, and printing references.
Reference kinds
| Kind | Factory | Shape | Where you see it |
|---|---|---|---|
IdentifierRef | idRef(identifier, type?) | { identifier, type? } | Generated catalog constants, objects in GoodData Cloud and GoodData.CN |
UriRef | uriRef(uri) | { uri } | Objects addressed by URI |
LocalIdRef | localIdRef(localIdentifier) | { localIdentifier } | References between items inside one execution definition |
ObjRef is IdentifierRef | UriRef. ObjRefInScope adds LocalIdRef.
Compare two references
Use areObjRefsEqual. Do not compare identifier fields yourself.
import { areObjRefsEqual, attributeDisplayFormRef, filterObjRef, type IFilter } from "@gooddata/sdk-model";
import * as Md from "./catalog.js";
const regionDisplayForm = attributeDisplayFormRef(Md.Region.Default);
function findRegionFilter(filters: IFilter[]): IFilter | undefined {
return filters.find((filter) => areObjRefsEqual(filterObjRef(filter), regionDisplayForm));
}
Equality rules:
- Two identifier references are equal when their identifiers match.
typeis compared only when both carry one. - An identifier reference never equals a URI reference, even when both point to the same object.
- Two
nullorundefinedvalues are equal. Onenulland one reference are not.
Use a reference as a key
serializeObjRef returns a stable string that keeps the kind and the type. deserializeObjRef turns it back into a reference.
import { deserializeObjRef, idRef, measureItem, serializeObjRef, type IMeasure, type ObjRef } from "@gooddata/sdk-model";
const titles = new Map<string, string>();
function rememberTitle(ref: ObjRef, title: string): void {
titles.set(serializeObjRef(ref), title);
}
function titleOf(measure: IMeasure): string | undefined {
const ref = measureItem(measure);
return ref ? titles.get(serializeObjRef(ref)) : undefined;
}
// Round trip
const restored = deserializeObjRef(serializeObjRef(idRef("f_owner.region_id", "displayForm")));
Keys are strict: idRef("x") and idRef("x", "displayForm") produce different keys. When you build references to key by, pass the same type argument every time, or key by the reference the SDK gave you.
Narrow before reading a field
Use the type guards. A cast such as ref as IdentifierRef compiles, but when a URI reference reaches it, ref.identifier is undefined, and the bug shows up later as a missing key.
import { isIdentifierRef, type ObjRef } from "@gooddata/sdk-model";
function identifierOf(ref: ObjRef): string | undefined {
return isIdentifierRef(ref) ? ref.identifier : undefined;
}
isUriRef and isLocalIdRef work the same way.
Print a reference
objRefToString returns the bare identifier, URI, or local identifier. Use it for logs, debugging, and test output.
objRefToString drops the kind and the type. idRef("x", "displayForm"), idRef("x", "dataSet"), and uriRef("x") all print "x", so a Map or Set keyed by it merges different objects.Helper summary
| Task | Helper |
|---|---|
| Create a reference | idRef, uriRef, localIdRef |
| Compare | areObjRefsEqual(a, b) |
Key a Map, Set, or Record | serializeObjRef(ref), deserializeObjRef(value) |
| Narrow | isIdentifierRef, isUriRef, isLocalIdRef, isObjRef |
objRefToString(ref) | |
| Get the reference out of an SDK object | attributeDisplayFormRef(attribute), measureItem(measure), filterObjRef(filter) |
Related
Create and modify IAttribute objects with newAttribute, apply optional local identifiers and alias overrides.
Create simple measures with newMeasure, arithmetic measures from two operands with newArithmeticMeasure, and inline MAQL measures with newInlineMeasure.
Split an IFilter array by kind, find the filter for a display form, read or replace the selected elements, and detect an empty selection without reading filter internals.
Load measures, attributes, and date datasets while your application runs, and turn catalog items into IMeasure and IAttribute objects.