Inaccessible Attributes

627
7
02-21-2024 07:08 PM
Med-Karim-Rouissi
Emerging Contributor

Hello everybody,

I am using the ArcGIS API for JavaScript version 4.24. I have created an HGIS (Historical Geographic Information System) application for the tribes of Arabia. My map consists of multiple genealogically layered overlays. When I click on a territory of a tribe, I can retrieve a list of successive parent tribes to which it belongs in the form of clickable buttons, and this works perfectly.

On the buttons for the parent tribes, I intended to display the "Name" attribute, which is in English and Arabic. It displayed correctly with test data, but after publishing my data to ArcGIS Online, I am unable to access all my attributes. The console log only provides the ID and the "Name_en" attribute. However, using the 'PopupTemplate' I can retrieve all attributes.

Below is a snippet of my code, along with screenshots showing the list display with the "Name_en" attribute and the empty list display when I use the "Name" attribute.

forum_esri.png

 

 

let poptemp;

// Create PopupTemplate for displaying information
poptemp = new PopupTemplate({
    title: "{Name}",
    content: [{
        type: "fields",
        fieldInfos: [{
            fieldName: "Name_ar",
            label: "Name_ar"
        }, {
            fieldName: "Name_en",
            label: "Name_en"
        }, {
            fieldName: "Wiki_ar_link",
            label: "Wiki_ar_link"
        }, {
            fieldName: "Wiki_en_link",
            label: "Wiki_en_link"
        }]
    }]
});

let Mygraphic = new Graphic({
    popupTemplate: poptemp
});

const Mycontainer = document.getElementById("gridDiv");
Mycontainer.innerHTML = "";

const listNode = document.getElementById("new_graphic");

let feature_1 = new Feature({
    graphic: Mygraphic,
    view: view,
    container: Mycontainer
});

let highlight;

let results;
let result;

// Event handler for list item clicks
function onListClickHandler(event) {
    const target = event.target;
    const resultId = target.getAttribute("data-result-id");
    result = resultId && results && results[parseInt(resultId, 10)];

    view.whenLayerView(result.graphic.layer).then(function (layerView) {
        if (result && results.length > 0) {
            highlight && highlight.remove();

            view
                .goTo(result.graphic.geometry.extent.expand(1))
                .then(function () {
                    result.graphic.layer.popupTemplate = poptemp;
                    feature_1.graphic = result.graphic;
                    highlight = layerView.highlight(result.graphic);
                    handleClick(result);
                });
        } else {
            feature_1.graphic = graphic;
        }
    });
};

// Function to update the displayed list
function updateList(results) {
    const fragment = document.createDocumentFragment();
    results = results.reverse();

    results.forEach(function (result, index) {
        const attributes = result.graphic.attributes;
        const li = document.createElement("li");
        li.classList.add("panel-result");
        li.tabIndex = index;
        li.setAttribute("data-result-id", index);
        li.textContent = attributes.Name;

        fragment.appendChild(li);
    });

    listNode.innerHTML = "";
    listNode.appendChild(fragment);
    listNode.style.display = "block";
    listNode.addEventListener("click", onListClickHandler);
};

 

Thank you in advance for your help.

Karim

0 Kudos
7 Replies
Med-Karim-Rouissi
Emerging Contributor

 

Screenshots showing the functionality of the application

 

1.png

 

2.png

 

3.png

 

4.png

 

0 Kudos
LaurenBoyd
Esri Contributor

Hi @Med-Karim-Rouissi -

Does the layer have the Name field included in the outFields property? You may need to make sure the layer has those needed attributes when you create it. Setting those fields in the popup template content does not automatically include those attributes for each feature in the layer.

Lauren
0 Kudos
Med-Karim-Rouissi
Emerging Contributor

Hello LaurenBoyd,
Indeed the "outFields" are configured:
outFields: ["*"]
I also tried indicating them one by one, it doesn't change anything!
What intrigues me is that I could get the "Name" attribute on the buttons, when I was working on my project a few months ago, and with console.log I could see all my attributes, but not anymore. Is there a bug on Arcgis Online?

  require([
    "esri/Map",
    "esri/Basemap",
    "esri/views/MapView",	
    "esri/layers/FeatureLayer",
    "esri/layers/Layer",
	"esri/geometry/Extent",
    "esri/widgets/Legend",
    "esri/widgets/LayerList",
    "esri/widgets/Expand",
    "esri/widgets/Feature",
    "esri/Graphic",
	"esri/layers/GraphicsLayer",
	"esri/widgets/Home",
    "esri/PopupTemplate",
    "esri/widgets/ScaleBar",
	"esri/geometry/Point",
    "esri/symbols/SimpleMarkerSymbol",
    "esri/Color",
    "dojo/parser",
	"dojo/text!./data/tree.nwk",
    "dojo/domReady!"

  ], function (
    Map,
    Basemap,
    MapView,
    FeatureLayer,
    Layer,
	Extent,
    Legend,
    LayerList,
    Expand,
    Feature,
    Graphic,
	GraphicsLayer,
	Home,
    PopupTemplate,
    ScaleBar,
	Point,
	SimpleMarkerSymbol,
	Color,
	parser,
	newickSource
  ) {
    Layer.fromPortalItem({
      portalItem: {
        id: "a3fc6bbaaec642ce81e46711e08df208"
      },
      outFields: ["*"],
	  visible: true
    }).then(function (groupLayer) {
      const basemap = new Basemap({
        portalItem: {
          id: "00c8181753cd4673810a1ede1f52a922"
        }
      });

      const map = new Map({
        basemap: basemap,
        layers: groupLayer
      });
	  
      let mainExtent = new Extent({
        xmin: 30,
        ymin: 16,
        xmax: 60,
        ymax: 36,
        spatialReference: {
          wkid: 4326
        }
     });	  
   
      const view = new MapView({
        container: "viewDiv",
        map: map,
        center: [45.0, 26.0],
	    zoom: 4,
        popup: {
          highlightEnabled: false,
          autoOpenEnabled: false
        }
      });
      
	  const legend = new Legend({ view: view });
      const legendExpand = new Expand({
        expandTooltip: "Show Legend",
        expanded: false,
        view: view,
        content: legend
      });
      const layerList = new LayerList({ view: view });
      const scaleBar = new ScaleBar({ view: view, unit: "dual" });
	  const homeWidget = new Home({view: view});
  
      view.ui.add(layerList, "top-right");
      view.ui.add(legendExpand, "top-right");
      view.ui.add(scaleBar, { position: "bottom-left" });
	  view.ui.add(homeWidget, "top-left");
	  view.ui.add("logoDiv", "bottom-right");
	  
	  // Récupérer le bouton
       const toggleButton = document.getElementById("logoDiv");
      // Ajouter un gestionnaire d'événements pour le clic sur le bouton
       toggleButton.addEventListener("click", toggleLines);
0 Kudos
LaurenBoyd
Esri Contributor

I think the issue might be that the outFields are being passed as a parameter into the Layer.fromPortalItem method - this method only takes a portalItem as an option. Can you try setting the outFields property on the layer returned from the promise of that method between line 52 and 53 like this?

Layer.fromPortalItem({
  portalItem: {
    id: "cfeb916a04a841e093786e3195a69231"
  }
}).then((layer) => {
  layer.outFields = ['*'];
  ...
});

Here's a smaller example app that does this and prints out the attributes of the clicked feature in the console: https://codepen.io/laurenb14/pen/zYbVPdm?editors=1000 

Lauren
0 Kudos
Med-Karim-Rouissi
Emerging Contributor

I tried this code, it didn't change anything, I don't always see my attributes, and writing "layer" instead of "Layer" gives me an error in the console "Uncaught (in promise) ReferenceError: layer is not defined"

 

    Layer.fromPortalItem({
      portalItem: {
        id: "a3fc6bbaaec642ce81e46711e08df208"
      }
    //    outFields: ["*"],
	//    visible: true
    }).then(function (groupLayer) {
	  Layer.outFields = ['*'];
      const basemap = new Basemap({
        portalItem: {
          id: "00c8181753cd4673810a1ede1f52a922"
        }
      });

 

I also tried with "groupLayer", nothing changes either

    Layer.fromPortalItem({
      portalItem: {
        id: "a3fc6bbaaec642ce81e46711e08df208"
      }
    //    outFields: ["*"],
	//    visible: true
    }).then(function (groupLayer) {
      groupLayer.outFields = ['*'];
      const basemap = new Basemap({
        portalItem: {
          id: "00c8181753cd4673810a1ede1f52a922"
        }
      });

 

0 Kudos
Med-Karim-Rouissi
Emerging Contributor

All layers in my project have the same attributes, here is an example

 

data.png

 

0 Kudos
Med-Karim-Rouissi
Emerging Contributor

Hello,

Following tests and verifications, I realized that I should share with you the part of the code that handles the click. Upon closer analysis, I found that I only have access to the attribute that manages the graphical semiotics "Name_en."

Therefore, I believe I can recreate my map using the graphical semiotics based on the "Name" attribute, which contains both the name in English and Arabic, instead of the "Name_en" attribute that only contains the name in English. This resolves my issue.

However, I am facing difficulties understanding the behavior of my code. Rather than completely redoing the map, I would like to seek your expertise in solving this problem.

Best regards,

 

// Manage map click
view.on("click", async function (event) {
    highlight && highlight.remove();

    const response = await view.hitTest(event);
	console.log("response", response);
    results = response.results;
	console.log("results", results);
    results.pop();
    const result_0 = results[0];

    if (result_0) {
		console.log("Attributes:", result_0.graphic.attributes);
        handleMapClick(result_0);
    }
});

 

0 Kudos