Issues with updating a TrackedEntityInstance via DataMutation

I’m working on an embedded custom react application within DHIS2 - I have gone through the documentation from here - How to use the Data Query Playground | DHIS2 Developer Portal - and have been able to get a new Instance created in the system with no issues. My major issue is relating to the updates of trackedEntityInstances.

I have the following sample JSON - which will import via the import app:

{
    "trackedEntityInstances": [  {
            "orgUnit": "VgrqnQEtyOP",
            "trackedEntityInstance": "HuZ5Kc4GSUe",
            "trackedEntityType": "W9FNXXgGbm7",
            "attributes": [{
                    "attribute": "jv1fu2pDYKE",
                    "value": "01"
                }, {
                    "attribute": "zh91RcBXyEf",
                    "value": "2004-01-01"
                }, {
                    "attribute": "esA6f27JSQM",
                    "value": "55"
                }, {

                    "attribute": "ggdR2bH42l3",
                    "value": "1"
                }, {
                    "attribute": "Zb9icCay6Ka",
                    "value": "0"
                }
            ]
        } 
    ]
}

When attempting to perform the update using this code below

const handleFormSubmit = async (event) => {
        event.preventDefault();

        const url = 'https://<URL>/api/trackedEntityInstances'; // 
        const jsonData = {
            trackedEntityInstances: [
              {
                orgUnit: 'VgrqnQEtyOP',
                trackedEntityInstance: 'HuZ5Kc4GSUe',
                trackedEntityType: 'W9FNXXgGbm7',
                attributes: [
                  { attribute: 'jv1fu2pDYKE', value: '01' },
                  { attribute: 'zh91RcBXyEf', value: '2004-01-01' },
                  { attribute: 'esA6f27JSQM', value: '55' },
                  { attribute: 'ggdR2bH42l3', value: '1' },
                  { attribute: 'Zb9icCay6Ka', value: '0' },
                ],
              },
            ],
        };
        
        try {
            const response = await fetch(url, {
              method: 'POST',
              headers: {
                'Content-Type': 'application/json',
              },
              body: JSON.stringify(jsonData),
            });
      
            if (response.ok) {
              const data = await response.json();
              setResponseMessage('Data uploaded successfully!');
              console.log(data);
            } else {
              setResponseMessage('Failed to upload data');
              console.error('Error:', response.statusText);
            }
          } catch (error) {
            setResponseMessage('An error occurred while uploading data');
            console.error('Error:', error);
          }
    };

going via Post I am getting a "Unexpected token ‘<’, "<!DOCTYPE “… is not valid JSON” error.

Alternately I have attempted to just do a dummy update with the same data using the UseDataMutation methods in @dhis2/app-runtime. As shown below:

{
const [responseMessage, setResponseMessage] = useState('');

  const mutation = {
    resource: 'trackedEntityInstances',
    type: 'update',
    data: {
      trackedEntityInstances: [
        {
          orgUnit: 'VgrqnQEtyOP',
          trackedEntityInstance: 'HuZ5Kc4GSUe',
          trackedEntityType: 'W9FNXXgGbm7',
          attributes: [
            { attribute: 'jv1fu2pDYKE', value: '01' },
            { attribute: 'zh91RcBXyEf', value: '2004-01-01' },
            { attribute: 'esA6f27JSQM', value: '55' },
            { attribute: 'ggdR2bH42l3', value: '1' },
            { attribute: 'Zb9icCay6Ka', value: '0' },
          ],
        },
      ],
    },
  };

  const [mutate, { error, loading }] = useDataMutation(mutation);

  const handleFormSubmit = async (event) => {
    event.preventDefault();
    try {
      const response = await mutate();

      if (!response || (error && error.length > 0)) {
        setResponseMessage('Failed to upload data');
        console.error('Error:', error);
      } else {
        setResponseMessage('Data uploaded successfully!');
        console.log(response);
      }
    } catch (error) {
      setResponseMessage('An error occurred while uploading data');
      console.error('Error:', error);
    }

Going this route - I’m getting an Method not allowed

Can anyone advise on where I can find simple details of an update of an TrackedEntityInstance via the UseDataMutation - even an example via GitHub that I can compare where I’m going wrong.

If I update the type: ‘update’, to type: ‘create’, it runs without issue.

Hi @matthew_deas: glad to hear that you’ve been able to get your app up and running!

useDataMutation
If you want to make an update, you will need to provide an id for the tracked entity instance which you wish to update. If you provide an id in the query, the request will be sent to api/trackedEntityInstances/{yourID}. Currently, without the id, the request is sent to api/trackedEntityInstances. The update type is translated to a PUT request and api/trackedEntityInstances does not support PUT requests. This is why it works when you change the mutation type to create; api/trackedEntityInstances does support POST requests and when you use create mutation, you will create a new tracked entity instance.

The documentation for useDataMutation might be useful here: app-runtime/examples/cra/src/components/Indicator.js at master · dhis2/app-runtime · GitHub and particularly, the linked example (app-runtime/examples/cra/src/components/Indicator.js at master · dhis2/app-runtime · GitHub) can show you how to structure a mutation query to pass an id.

Issues with fetch:
We encourage people to use our useDataQuery and useDataMutation hooks for interacting with the api as they include some optimizations under the hood, but if you do want to directly use fetch, that should be possible.
Based on the error here ("Unexpected token ‘<’, "<!DOCTYPE" ... is not valid JSON"), it looks the specific problem is occurring at body: JSON.stringify(jsonData). I assume that you are getting this error because the POST is not going through and you’re being redirected (you can check the response in the network tab). I think setting {credentials: "included"} in fetch options would resolve that issue.
Note that the points above (about pointing to api/trackedEntityInstances/{yourID} and using PUT request will also be relevant if this is intended to be an update of an existing tracked entity instance)

Hope that information helps you figure out the issue. Let us know how it goes and if we can help with anything else.

Hi @tzemp - Thank you so much for the response - think the confusion came in between how IDs are referred - TrackedEntityInstance - vs id - used interchangeably and in some places its tei etc.

I have worked it out with a demo update sequence which I can then adjust for implementation - decided to put this here if anyone else has the same question going forward.

I created this structure:

const testMutate = { "resource": "trackedEntityInstances", "type": "update", id: "HuZ5Kc4GSUe", "data": { orgUnit: 'VgrqnQEtyOP', attributes: [ { attribute: 'esA6f27JSQM', value: '10100' } ] } }

Note that the attributes to be updated are in based on the overall structure of the TrackedEntityInstance object - this ran without issue.

Had previously had the indicators and programs examples working - but they didnt have the added attributes complexity.

Thanks again for your reply

1 Like