Sync Protocol REST APIs: How to send PUT request for inserting a row?

I tried to send a PUT request to the server, but kept on receiving error 500, which is not descriptive of the issue. I think I am not using this API correctly: https://docs.odk-x.org/odk-2-sync-protocol/#alter-data-rows-insert-update-or-delete-api. What should be the formatting of data?

Thanks.

This is my code:

	var request = new XMLHttpRequest()
	request.open('PUT', domain.concat(appId).concat('/tables/').concat(tabid).concat('/ref/').concat(schemaETag).concat('/rows'), true, 'username', 'password')
	request.setRequestHeader("Content-type", "application/json")
	var data = {...}
	request.onload = function() {
		if (request.status >= 200 && request.status < 400) {
			console.log('got in', request.status)
		} else {
			console.log('request status is:', request.status)
		}
	}
	request.send(data)
}```

For testing the API you might have find it easier to debug if using a rest client such as Postman or Insomnia.

Make sure your domain is setup to include /odktables, and then the path as shown in the docs is {appId}/tables/{tableId}/ref/{schemaETag}/rows.

You might also want to double-check how you’re passing the auth (easier to do in the rest client)

Then for the payload, I think it’s similar to what you see from a GET request, with a few field ommisions which are generated server side. Something along the lines of:

{
	"dataETag":"..." <- add from table meta,
	"rows": [{
      "rowETag": "..." <- add generated UUIDv4,
      "deleted": false,
      "formId": null,
      "locale": "en_GB",
      "savepointType": "COMPLETE",
      "savepointTimestamp": "" <- add generated timestamp,
      "savepointCreator": "anonymous",
      "orderedColumns": [
        {
          "column": "My_Var_1", <- Format your field-value pairs here
          "value": "Example Code"
        },
      ],
      "id": "..." <- add generated UUIDv1,
      "filterScope": {
        "defaultAccess": "FULL",
        "rowOwner": "ANONYMOUS",
        "groupReadOnly": "FALSE",
        "groupModify": "TRUE",
        "groupPrivileged": "TRUE"
      }
	}]
}

Although as an extra word of caution, if doing things direct via api you may have a few extra challenges when writing data as typically most of the default java methods modify data in small ways before sending to the server (fine for reading data though), and combine with additional device methods. E.g., when creating a table the server will expect to also find the correct definition files uploaded, or when reading data some fields might be stripped or edited.

3 Likes

Thank you so much! This is very helpful!

1 Like