I’m trying to create a Custom Visualization using ...
# gooddata-ui
e
I’m trying to create a Custom Visualization using the <Execute> component to display some tabular data in a specific way. However the
executeAfm
call is failing (400) and returning this error:
Copy code
{
  "errorClass": "InvalidDimensionException",
  "trace": "",
  "message": "Specified 'measureGroup' but no measures found in AFM",
  "component": "Webapp",
  "errorId": "46e9b718-a353-4e19-9e02-fb0b429cbd30",
  "errorCode": "gdc111",
  "parameters": []
}
The data I am trying to fetch consists only of attributes, and I noticed that in this request’s payload it is appending
"measureGroup"
to the dimensions property of resultSpec:
Copy code
{
  "afm": {
    "attributes": [
      {
        "displayForm": {
          "uri": "/gdc/md/mi3l622mq24o9wbj20d3y7ybh96wbkfs/obj/21736"
        },
        "localIdentifier": "ee076055bd3a4f75becbd7398b891fca"
      },
      {
        "displayForm": {
          "uri": "/gdc/md/mi3l622mq24o9wbj20d3y7ybh96wbkfs/obj/22028"
        },
        "localIdentifier": "0896b64b43f04b5e85dc257517ad7e58"
      },
      {
        "displayForm": {
          "uri": "/gdc/md/mi3l622mq24o9wbj20d3y7ybh96wbkfs/obj/22320"
        },
        "localIdentifier": "a67a04e3db5143e4a5c5ee553e49c61c"
      },
      {
        "displayForm": {
          "uri": "/gdc/md/mi3l622mq24o9wbj20d3y7ybh96wbkfs/obj/22612"
        },
        "localIdentifier": "387eee9ccb1f43c685af92e90785e5e0"
      },
      {
        "displayForm": {
          "uri": "/gdc/md/mi3l622mq24o9wbj20d3y7ybh96wbkfs/obj/22904"
        },
        "localIdentifier": "c5050ef3108e4efdb3b1c60dd73c90eb"
      },
      {
        "displayForm": {
          "uri": "/gdc/md/mi3l622mq24o9wbj20d3y7ybh96wbkfs/obj/22916"
        },
        "localIdentifier": "774662516163499486f53106f2110d99"
      }
    ]
  },
  "resultSpec": {
    "dimensions": [
      {
        "itemIdentifiers": [
          "774662516163499486f53106f2110d99"
        ]
      },
      {
        "itemIdentifiers": [
          "ee076055bd3a4f75becbd7398b891fca",
          "0896b64b43f04b5e85dc257517ad7e58",
          "a67a04e3db5143e4a5c5ee553e49c61c",
          "387eee9ccb1f43c685af92e90785e5e0",
          "c5050ef3108e4efdb3b1c60dd73c90eb",
          "measureGroup"
        ]
      }
    ]
  }
}
Is that correct behavior? Or is an <Execute> without any measures in seriesBy/slicesBy incorrect usage? I have another Custom Viz that does feature a measure and that one works fine.
d
Hi Evan, the “resultSpec” cannot contain the “measureGroup” element if there are no measures in the “afm” object. But this should be handled by the Execute component internally 😕 can you please share the code of where you call the Execute component? I am mostly interested in the prop values for
seriesBy
and
slicesBy
.
e
Copy code
const TimelineChart = ({
    insightId,
    filters,
    config,
}: ITimelineChartProps) => {
    const gdBackend = useBackendStrict();
    const gdWorkspace = useWorkspaceStrict();
    const [ series, setSeries ] = useState<IAttributeOrMeasure[]>();
    const [ slices, setSlices ] = useState<IAttributeOrMeasure[]>();
    const [ error, setError ] = useState<ErrorTypes>();

    useEffect(() => {
        gdBackend.workspace(gdWorkspace).insights().getInsight({identifier: insightId}).then(({ insight }) => {
            console.log('timeline insight', insight);
            const { buckets, visualizationUrl, filters } = insight;
            if (visualizationUrl !== 'local:table') {
                setError(ErrorTypes.IncompatibleGdChartType);
                return;
            }
            if (buckets.length !== 1 || buckets[0].localIdentifier !== 'attribute') {
                setError(ErrorTypes.GdDataError);
                return;
            }

            setSeries(buckets[0].items);
        }).catch(reason => {
            console.error('getInsight catch', reason);
            setError(ErrorTypes.InsightDoesNotExist);
        });
    }, [insightId]);

    if (series === undefined) return null;

    return <Execute
        seriesBy={series}
        children={(execution) => {
            console.log('Render <Execute> children', execution);
            const data = execution.result?.data();
            console.log('data', data);
            return <div>Execute</div>
        }}
    />;
};
This component is essentially an alternate rendering of a specific kind of Table chart. In the
getInsight
block we are only expecting attribute data so after verifying that that’s all there it’s loaded into into the
series
state which is used for Execute’s
seriesBy
In the screenshot you can see that the executeAfm payload includes “measureGroup” along with all of the attribute ids
d
Hi again Evan, I reproduced your problem and went through the code. It seems there is a problem in the code that generates the executions (it does not handle the case when there are no measures in the
seriesBy
) 😞 we will take a deeper look and try to fix it, in the meantime what you can probably do is to put some measure there and ignore it, if that makes sense for your use case
Just an FYI: we just merged a PR that should fix this: https://github.com/gooddata/gooddata-ui-sdk/pull/2568 it will be a part of the next release of the GoodData.UI 🙂 thank you for providing the information to reproduce this and sorry for the inconvenience
e
It seems like I can just make a measure out of count for one of the attributes right? That’ll work for now. Thanks!
d
Yes, that is a reasonable workaround 🙂
e
Trying to get it to build that measure programmatically. I noticed that the attribute from the insight definition only has its displayForm’s uri, but to make a count measure I need the actual attribute itself’s uri. What’s the best way to get that?
d
I think the best way would be something like
Copy code
import { uriRef } from "@gooddata/sdk-model";

const displayForm = await backend
    .workspace(workspace)
    .attributes()
    .getAttributeDisplayForm(uriRef(displayFormUri));

const attributeRef = displayForm.attribute;
👍 1