How do I get an array to show up in a GeoJSONLayer's attributes?

668
3
08-06-2020 08:07 AM
KDimitrov
New Contributor II

This is my code:

var layer = new GeoJSONLayer({

url: "<URL>",
outFields: ["*"],
popupTemplate: {

title: "{name}",
content: generateContent

},

});

function generateContent(feature){

var graphic = feature.graphic;
var attributes = graphic.attributes;

console.log(attributes); // every attribute shows up, but the array attribute is missing

var content = "";
return content;

}
map.layers.add(layer);

Firstly none of my attributes were showing up, until I added this to my layer parameters:

outFields: ["*"]


Sadly setting the outFields didn't include the array in the attributes.
I have checked the json and the  array attribute is there.

What could be happening here for the array not to show up in the attributes?

3 Replies
KDimitrov
New Contributor II

Anybody?

0 Kudos
AshleyLong
New Contributor

Hi. I recently encountered the same issue, where any array property values in my geoJSON weren't getting pulled into my Feature Layer, and I was unable to access them in my popups. After revisiting the documentation, I think herein lied our problem: 

[From the docs:] "Each GeoJSONLayer will only accept one schema of the properties. The fields property can be used to specify the desired fields for the layer. If fields is not defined, the schema used by the first feature will be used to deduce the fields schema for the layer."

To remedy this, I declared field types for all of my geoJSON properties just to be safe, and for the fields with array values, I specified them as strings in hopes that the API would convert them to strings, and it worked.

// GeoJSON snippet:

{
      "type": "Feature",
      "geometry": {
            "type": "Point",
            "coordinates": [ -1.149170, 52.955120 ]
      },
      "properties": {
            "name": ["array", "of", "values"]

      }

}

// GeoJSON layer setup:

const geoJSONLayer = new GeoJSONLayer({
      url: URL.createObjectURL(blob),
      renderer: renderer,
      popupTemplate: template,
      outFields: ["*"],
      fields: [
            new Field({
                  "name": "arrayField",
                  "alias": "Array Field",
                  "type": "string" <==== this will join the offending array into a string
            })
      ]
});

Now, I can't say whether this is the recommended way of doing this since the API will still warn you in the console about invalid field types. However, none of the other available field types seem appropriate for outputting arrays, and while it feels a little messy, it will get your array property values to populate. Just be sure to require() the Fields module first, or you can use the autocasted implementation and skip the require().

If anyone else knows of a cleaner way (or why GeoJSONLayers are incapable of outputting array-type geoJSON properties in the first place), please chime in!

0 Kudos
KDimitrov
New Contributor II

I solved it with a Promise.

Inside the returned promise, I make an ajax call with the element ID. I had to write my own little API to get the properties by providing the ID. This example uses jQuery for the $.ajax call to the api.

The popup shows a little loader while the promise works on retrieving the data.

var layer = new GeoJSONLayer({

url: "<URL>",
outFields: ["*"],
popupTemplate: {

title: "{name}",
content: generateContent

}

});

function generateContent(feature) {

var graphic = feature.graphic;

var attributes = graphic.attributes;

let promise = new Promise((resolve, reject) => {

$.ajax({

url: "<PROPERTIES API URL>",
method: "post",
data: {

id: attributes["id"]

}

}).done(function(result) {

       // the data we need

let properties = result.data;


// popup content needs to follow these rules:
// https://developers.arcgis.com/javascript/latest/api-reference/esri-PopupTemplate.html#content
let content = "";


resolve(content);

}).fail(function(xhr, textStatus, errorThrown) {

console.error(textStatus, errorThrown);

});

});
return promise;

}
map.layers.add(layer);

0 Kudos