Select to view content in your preferred language

Exclude Null Values In Map Viewer Pop-Ups (Arcade)

1009
1
Jump to solution
08-16-2023 06:35 AM
moremeowbell
New Contributor III

I have scoured posts and am unable to find a way to exclude fields that have Null values in pop-ups. I am using Map Viewer, but not opposed to using Map Viewer Classic or even ArcGIS Pro to get this functionality to work.

From what I understand, Arcade is a non-object oriented, JavaScript-based language (please correct me if I'm wrong!).

Here are some code snippets of what I have tried and how they failed.

var popUpContent = "";
var fieldsToInclude = ["objectid", "symbol_group"];
var isFirstIteration = true;

var feat = FeatureSetByName($map, "Wells TVD 20K Grid", fieldsToInclude, false);

Function GetAlias(f, fldname) {
    var scheme = Schema(f);
    var flds = scheme["fields"];
    for (var i in flds) {
        var fldinfo = flds[i];
        if (fldinfo["name"] == fldname) {
            return fldinfo["alias"];
        };
    };
    return fldname;
};

for (var f in feat) {
    for (var field in fieldsToInclude) {
        var fieldName = fieldsToInclude[field];
        if (isFirstIteration){
            if (!IsEmpty(f[fieldName]) && f[fieldName] != 0) {
                var alias = GetAlias(f, fieldName);
                popUpContent += alias + " = " + f[fieldName] + TextFormatting.NewLine;
            };
        };
    };
    isFirstIteration = false;
};

return popUpContent;

Failure: Not returning the correct attribution data, but it does exclude Null values and Aliases.

 

var popUpContent = "";
var fieldsToInclude = ["objectid", "symbol_group"];
var isFirstIteration = true;

var feat = FeatureSetByName($map, "Wells TVD 20K Grid", fieldsToInclude, false);

Function GetAlias(f, fldname) {
    var esquema = Schema(f);
    var flds = esquema["fields"];
    for (var i in flds) {
        var fldinfo = flds[i];
       
        if (fldinfo["name"] == fldname) {
            return fldinfo["alias"];
        };
    };
    return fldname;
};


for (var f in feat) {
    var row = {};
    for (var field in fieldsToInclude) {
        var fieldName = fieldsToInclude[field];
        if (!IsEmpty(f[fieldName]) && f[fieldName] != 0) {
            var alias = GetAlias(f, fieldName);
            row[alias] = f[fieldName];
        }
    }
    return row
}

Failure: Not returning the correct attribution data, but it does exclude Null values and Aliases.

 

var fieldsToInclude = ["tvd_ft_0",
                "well_status_type",
                "Symbology",
                "tvd_ft_bin_count"
                ];
var features = FeatureSetByName($map, 'Well Status-20K Grid', fieldsToInclude, false);
var aDict = Schema(features);
var aArray = aDict["fields"];
var output;

for (var i in $feature){
    if (!IsEmpty($feature[i]) &&
       ($feature[i] != 0)) {
        for(var j in aArray) {
            var dict = aArray[j];
            if (dict['name'] == i){
                output += dict['alias'] + ": " + $feature[i] + TextFormatting.NewLine + TextFormatting.NewLine;
            };
        };
    };
};
return output;

Failure: Not returning correct field names/ alisases

 

 

 

0 Kudos
1 Solution

Accepted Solutions
JohannesLindner
MVP Frequent Contributor

Your first two examples don't return the data you expect because you take the first feature of the layer, not the feature you clicked on. To access the current feature, use the $feature global, like you did in your third example.

I think your third example doesn't work because Arcade only loads fields if they are used in the expression.  This works great if you explicitly call your fields by using $feature["Field"] or $feature.Field . It doesn't work when you access fields by variable like $feature[fieldName]. In cases like this, you should tell Arcade to load all fields using Expects().

// define the requested field names
var fieldsToInclude = ["objectid", "TextField1"]

// Calling fields by variable instead of string literal can be icky,
// so we should tell Arcade that we expect all fields to be loaded
Expects($feature, "*")

// create a dictionary of {fieldName: fieldAlias}
var fieldData = Schema($feature).fields
var aliases = {}
for(var f in fieldData) {
  aliases[fieldData[f].name] = fieldData[f].alias
}

// define an empty array that stores the output lines
var popupLines = []

// loop over the requested field names
for(var f in fieldsToInclude) {
  // get the name, alias, and value of the field
  var fName = fieldsToInclude[f]
  var fAlias = aliases[fName]
  var fValue = $feature[fName]
  // if value is valid, append it to the array
  if(!Includes([null, 0, "", " "], fValue)) {
    Push(popupLines, `${fAlias}: ${fValue}`)
  }
}
// concatenate and return
return Concatenate(popupLines, TextFormatting.NewLine)

JohannesLindner_0-1692205123438.pngJohannesLindner_1-1692205136552.png

 


Have a great day!
Johannes

View solution in original post

1 Reply
JohannesLindner
MVP Frequent Contributor

Your first two examples don't return the data you expect because you take the first feature of the layer, not the feature you clicked on. To access the current feature, use the $feature global, like you did in your third example.

I think your third example doesn't work because Arcade only loads fields if they are used in the expression.  This works great if you explicitly call your fields by using $feature["Field"] or $feature.Field . It doesn't work when you access fields by variable like $feature[fieldName]. In cases like this, you should tell Arcade to load all fields using Expects().

// define the requested field names
var fieldsToInclude = ["objectid", "TextField1"]

// Calling fields by variable instead of string literal can be icky,
// so we should tell Arcade that we expect all fields to be loaded
Expects($feature, "*")

// create a dictionary of {fieldName: fieldAlias}
var fieldData = Schema($feature).fields
var aliases = {}
for(var f in fieldData) {
  aliases[fieldData[f].name] = fieldData[f].alias
}

// define an empty array that stores the output lines
var popupLines = []

// loop over the requested field names
for(var f in fieldsToInclude) {
  // get the name, alias, and value of the field
  var fName = fieldsToInclude[f]
  var fAlias = aliases[fName]
  var fValue = $feature[fName]
  // if value is valid, append it to the array
  if(!Includes([null, 0, "", " "], fValue)) {
    Push(popupLines, `${fAlias}: ${fValue}`)
  }
}
// concatenate and return
return Concatenate(popupLines, TextFormatting.NewLine)

JohannesLindner_0-1692205123438.pngJohannesLindner_1-1692205136552.png

 


Have a great day!
Johannes