I'm not sure if anyone has written about this before, so here's a nice little writeup of a solution to a common problem:
A frequent issue with popups is only showing the fields that aren't empty. This comes up on Esri Community all the time, and they've written a few support articles about it over the years.
However, the common solutions always involve listing out each field to check whether or not it's empty, something like
Having finally gotten in a position today where I needed to filter 50-odd fields down to something usable, here's a rough snippet that will get all of those empty fields out of the way and return an Arcade Fields Element. For more information on these, check out this blog and then the documentation.
Expects($feature, "*")
var featdict = Dictionary($feature)["attributes"]
var fieldInfos = []
for (var fie in featdict){
if (!IsEmpty(featdict[fie])){
var fInfo = {"fieldName": fie}
Push(fieldInfos,fInfo)
}
}
return {
type : 'fields',
"fieldInfos" : fieldInfos
}
If you really care about field order, you can add a whitelist of fields in the order you want and just use that instead. You still have to type out the fields you care about, but you don't have to do any tedious checking for each possible field. The important thing is looping using the feature's attribute dictionary to loop through and find the fields you want.
Expects($feature, "*")
var featdict = Dictionary($feature)["attributes"]
var fieldInfos = []
var whiteList = ["projstatus","admu", "oprtr"]
for (var fie of whiteList){
if (!IsEmpty(featdict[fie])){
var fInfo = {"fieldName": fie}
Push(fieldInfos,fInfo)
}
}
return {
type : 'fields',
"fieldInfos" : fieldInfos
}
If you care about field order for only a few fields and don't care about the rest, you can use that whitelist first and then loop through the dictionary.
Expects($feature, "*")
var featdict = Dictionary($feature)["attributes"]
var fieldInfos = []
var ignoreFields = ["created_user", "globalid", "inspuuid",
"last_edited_date", "last_edited_user",
"mapmaxx", "mapmaxy", "mapminx", "mapminy",
"objectid"]
var orderList = ["cse_nr", "leg_cse_nr", "solotpass", "inspecdate"]
//loop through the ordered list first
for (var fie of orderList){
if (!IsEmpty(featdict[fie])){
var fInfo = {"fieldName": fie}
Push(fieldInfos,fInfo)
}
}
//Loop through all the other attributes
for (var fie in featdict){
// Double bars || for OR.
if (Includes(ignoreFields, fie) || Includes(orderList, fie)){
continue
}
if (!IsEmpty(featdict[fie])){
var fInfo = {"fieldName": fie}
Push(fieldInfos,fInfo)
}
}
return {
type : 'fields',
"fieldInfos" : fieldInfos
}
If you'd like to keep the order of the fields, you can use the feature's Schema instead.
Expects($feature, "*");
var fields = Schema($feature)["fields"];
var fieldInfos = [];
for (var field of fields) {
if (!IsEmpty($feature[field.name])) {
var fInfo = {fieldName: field.name}
Push(fieldInfos, fInfo)
}
}
return {
type: "fields",
fieldInfos: fieldInfos
};