JSON objects not maintaining order of original dataset

I have a dataset that I'm trying to convert into JSON for a table component. Everything seems to be working fine except the order of the columns is not staying the same as the order of the dataset, which I'd like to preserve. I'm also getting key errors, which I think has something to do with the Audit_ID being an int instead of a str.

As you can see below, I've had to str() the colValue to get the style to work.:

def transform(self, value, quality, timestamp):
	outputJSON = []
	
	styleOrange = {"backgroundColor": "#F7901D"}
	styleGreen = {"backgroundColor": "#00AA00"}
	
	for row in range(value.getRowCount()):
		rowObject = {"value": {}, "style": {}}
	
		for col in range(value.getColumnCount()):
			colName = value.getColumnName(col)
			colValue = value.getValueAt(row, col)
	
			rowObject['value'][colName] = colValue
	
			if colName == 'Audit_ID':
				if str(colValue) == '1536':
					rowObject['style'] = styleOrange
				elif str(colValue) == '1539':
					rowObject['style'] = styleGreen
	
		outputJSON.append(rowObject)
	
	return outputJSON

My efforts with OrderedDict have proved fruitless so far. Any help or insight is appreciated.

You cannot. Java mapping objects (into which all forms of jython dictionary are coerced in Perspective) do not maintain ordered keys. You must use the table's .columns property to enforce ordering.

My dataset is dynamic and columns may get added or dropped depending on the filters applied. I was hoping to add formatting to the columns without explicitly naming them in the .columns field prop

Dynamically generate your columns property from your dataset, too.

Sorry.

1 Like

dang...

So I did that.

def transform(self, value, quality, timestamp):
    outputObject = []
    
    if value.getRowCount() > 0:
        colObjects = []
        
        for col in range(value.getColumnCount()):
            colName = value.getColumnName(col)
            
            colObject = {
                "field": colName,
                "visible": True,
                "editable": True,
                "render": "auto",
                "justify": "auto",
                "align": "center",
                "resizable": True,
                "sortable": True,
                "filter": {
                    "enabled": False,
                    "visible": "always",
                    "string": {
                        "condition": "contains",
                        "value": ""
                    },
                    "number": {
                        "condition": "greater than",
                        "value": ""
                    },
                    "boolean": {
                        "condition": "true"
                    },
                    "date": {
                        "condition": "date equals",
                        "value": ""
                    }
                },
                "viewPath": "",
                "viewParams": {},
                "boolean": "checkbox",
                "numberFormat": "none",
                "dateFormat": "none",
                "width": 100,
                "strictWidth": False,
                "style": {},
                "header": {
                    "title": colName,
                    "justify": "auto",
                    "align": "center",
                    "style": {}
                },
                "footer": {
                    "title": "",
                    "justify": "auto",
                    "align": "center",
                    "style": {}
                }
            }
            
            colObjects.append(colObject)
        
        outputObject = colObjects
    
    return outputObject

It's sort of working, except those things reset when the dataset refreshes. I'm thinking I need to add some logic to change the value (numberFormat: number, for example) based on the column name.