Has this ever happened to you? You go to edit a field's List (AGOL / Enterprise term for a domain), and you get this message:
Not the most helpful of error messages, but if we take a look at our browser Developer Tools, we can see this response:
{
"error": {
"code":500,
"message":"JSONObject[\"description\"] is not a string.",
"details":[]
}
}
What's going on here? I can see that the description is null in the payload sent to the server:
... "description":null, ...
You could attempt to open the URL your request was sent to, edit the payload, and resubmit. But that feels a bit hacky.
There's something funny here, and a recent comment elsewhere led me to believe that this was a 10.9.1 issue. Regardless, I've got domains that do have descriptions, and I still get this message. Now, I could fix these domains by republishing the layer, but that's sort of like swatting a fly with a baseball bat. Some alternative method is needed.
Whether you've attempted to alter a list using Python or not, know that it doesn't have to be hard. But the update_definition method can be finicky. I mean, even the Portal GUI can't update the list for me!
The key to a smooth operation is to modify as little of the existing definition as possible. Writing up your own JSON from scratch can lead to a lot of less-than-helpful error messages. Instead, we'll pull the JSON definition of our layer into a dict and make modifications to it there.
Personally, I think this makes a great interactive Notebook. Having those intermediate outputs is really helpful here.
fs = gis.content.get('02803529b103488fb5f75bbd6b1cfe9c').layers[0]
json = fs.properties
If you have a lot of fields, it can be helpful to see the list index of each with a quick dict comprehension.
{x['name']:json['fields'].index(x) for (x) in json['fields']}
Which looks like this:
{
'objectid': 0,
'globalid': 1,
'uniquerowid': 2,
'complaint_year': 3,
'investigation_number': 4,
'date_recorded': 5,
'complaint_source': 6,
'complaint_details': 7,
'status': 8,
...
}
Using the list index (8 in this example), we can pull out the domain to look at it.
json['fields'][8]
Which looks like:
{
'nullable': True,
'editable': True,
'defaultValue': None,
'domain': {'name': 'service_3742b925bb7947d486f585b6b3c5564b_cvd_status',
'type': 'codedValue',
'codedValues': [{'code': '2', 'name': 'Open'},
{'code': '1', 'name': 'Pending'},
{'code': '0', 'name': 'Closed'}]},
'name': 'status',
'alias': 'Status',
'type': 'esriFieldTypeInteger'
}
Notices that the codedValues object is just a list, so we can use .append here. As long as we follow the same format for our new value, of course.
new_value = {'code': '3', 'name': 'Reopened for Review'}
json['fields'][8]['domain']['codedValues'].append(new_value)
Maybe you just need to correct a typo or something. Just reassign the value! If you need a reminder of the list index of your value (helpful when it's a long list), you can use another dict comprehension here.
json['fields'][8]['domain']['codedValues'][1]['name'] = 'Pending Appeal'
Being a list, it's as simple as using .pop, together with the list index of the item you want removed.
json['fields'][8]['domain']['codedValues'].pop(3)
We've modified our json object in place, changing only what needs changing. Passing it back to the server is simple:
fs.manager.update_definition(json)
That's it! Let me know if this doesn't work for you, or if you have other ways of doing it, I'd love to hear it.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.