Popups: Ignore Null Fields in a way that isn't super time-intensive

520
1
02-25-2026 09:47 AM
Labels (3)
AlfredBaldenweck
MVP Frequent Contributor

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 

IIF($feature["Meter_Meter_Flow"] == -999, "None", "inline")

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
}

Here's the output for this snippet.

 

Spoiler
Initial dictionary (featdict):

{"admu":"Rawlins Field Office","casetype":"Material_Sites","compaccept":"no","created_date":"2026-02-11T18:51:40.625Z","created_user":"Me","cse_nr":null,"cse_type_nr":"282102,282104,282106","finabvgnd":null,"finallin":"yes","finberm":null,"finbridge":null,"fincanal":null,"fincatlgrd":null,"finconform":"no","finculvrt":null,"fincuruse":"NA","finerosctl":"Poor","finfence":"NA","fingates":null,"finguywire":null,"finmettwr":null,"finmntnrd":null,"finpadcnd":null,"finpoles":null,"finrdcon":null,"finrow":null,"finrrrow":null,"finsafehaz":"None_present","finsgnge":null,"finsnwfnc":null,"finsrfdran":"Poor","finstruct":"Poor","fintenants":null,"finturbfnd":null,"finturbine":null,"finunauth":null,"finveg":null,"finweeds":"None_present","globalid":"{C157DC69-A345-4163-A7B2-90BF42C87257}","inspecdate":"2026-02-11T19:00:00.000Z","inspuuid":"{f50cbd9b-f7e7-4ef1-80c6-6932799130ad}","last_edited_date":"2026-02-23T16:03:13.469Z","last_edited_user":"Me","leg_cse_nr":"WYW._._12345","location":"See SRP","mapmaxx":-106.98491587,"mapmaxy":41.80265023,"mapminx":-107.49131026,"mapminy":41.79779847,"nextinsdat":"2029-02-10T19:00:00.000Z","nextinsreq":"Other","objectid":1,"oprtr":null,"projstatus":"In Operation","rcrd_acrs":null,"recorder":"Alfred Baldenweck","sendletter":"yes","solotpass":null}

Filtered list of fields (fieldInfos):

[{"fieldName":"admu"},{"fieldName":"casetype"},{"fieldName":"compaccept"},{"fieldName":"created_date"},{"fieldName":"created_user"},{"fieldName":"cse_type_nr"},{"fieldName":"finallin"},{"fieldName":"finconform"},{"fieldName":"fincuruse"},{"fieldName":"finerosctl"},{"fieldName":"finfence"},{"fieldName":"finsafehaz"},{"fieldName":"finsrfdran"},{"fieldName":"finstruct"},{"fieldName":"finweeds"},{"fieldName":"globalid"},{"fieldName":"inspecdate"},{"fieldName":"inspuuid"},{"fieldName":"last_edited_date"},{"fieldName":"last_edited_user"},{"fieldName":"leg_cse_nr"},{"fieldName":"location"},{"fieldName":"mapmaxx"},{"fieldName":"mapmaxy"},{"fieldName":"mapminx"},{"fieldName":"mapminy"},{"fieldName":"nextinsdat"},{"fieldName":"nextinsreq"},{"fieldName":"objectid"},{"fieldName":"projstatus"},{"fieldName":"recorder"},{"fieldName":"sendletter"}]

 

You can also tweak it to get rid of fields that you never want to see by adding in an "Ignore these fields" list.

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"]
for (var fie in featdict){
	if (Includes(ignoreFields, fie)){
		continue
	}
	if (!IsEmpty(featdict[fie])){
		var fInfo = {"fieldName": fie}
		Push(fieldInfos,fInfo)
	}
}

return { 
	type : 'fields', 
	"fieldInfos" : fieldInfos
}

 

Spoiler
fieldInfos:
[{"fieldName":"admu"},{"fieldName":"casetype"},{"fieldName":"compaccept"},{"fieldName":"created_date"},{"fieldName":"cse_type_nr"},{"fieldName":"finallin"},{"fieldName":"finconform"},{"fieldName":"fincuruse"},{"fieldName":"finerosctl"},{"fieldName":"finfence"},{"fieldName":"finsafehaz"},{"fieldName":"finsrfdran"},{"fieldName":"finstruct"},{"fieldName":"finweeds"},{"fieldName":"inspecdate"},{"fieldName":"leg_cse_nr"},{"fieldName":"location"},{"fieldName":"nextinsdat"},{"fieldName":"nextinsreq"},{"fieldName":"projstatus"},{"fieldName":"recorder"},{"fieldName":"sendletter"}]

 

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
}

 

Spoiler
fieldInfos:
[{"fieldName":"projstatus"},{"fieldName":"admu"}]

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
}

 

Spoiler
fieldInfos:
[{"fieldName":"leg_cse_nr"},{"fieldName":"inspecdate"},{"fieldName":"admu"},{"fieldName":"casetype"},{"fieldName":"compaccept"},{"fieldName":"created_date"},{"fieldName":"cse_type_nr"},{"fieldName":"finallin"},{"fieldName":"finconform"},{"fieldName":"fincuruse"},{"fieldName":"finerosctl"},{"fieldName":"finfence"},{"fieldName":"finsafehaz"},{"fieldName":"finsrfdran"},{"fieldName":"finstruct"},{"fieldName":"finweeds"},{"fieldName":"location"},{"fieldName":"nextinsdat"},{"fieldName":"nextinsreq"},{"fieldName":"projstatus"},{"fieldName":"recorder"},{"fieldName":"sendletter"}]

Related Ideas:

I'm sure I'll continue to refine this, but it's a pretty good start for me today.

1 Reply
KenBuja
MVP Esteemed Contributor

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
};