Popup template loses info in ESRI Javascript version 4.17

1216
5
Jump to solution
12-08-2020 01:09 PM
don-EMerson
New Contributor II

When I am zoomed out so that the popup template has multiple items,the items after the first item (see attached image) do not have the attributes. They come back as undefined.

Here is the code to duplicate it.

 

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Get Data Grid  </title>
 
      
    <link rel="stylesheet" href="https://js.arcgis.com/4.14/esri/css/main.css">
    <script src="https://js.arcgis.com/4.14/"></script>
</head>
<body>


    <div class="container body-content">







        <script>











            function generateRenderer() {
                if (legendOn) {
                    var typeParams = {
                        layer: csvLayer,
                        numTypes: -1,
                        field: "ClassName",

                        view: view,
                        legendOptions: {
                            title: "VGS Data Points"
                        }
                    };
                    typeCreatorProxy
                        .createRenderer(typeParams)
                        .then(function (response) {
                            // set the renderer to the layer and add it to the map
                            csvLayer.renderer = response.renderer;
                            //map.add(csvLayer);
                        })
                        .catch(function (error) {
                            console.error("there was an error: ", error);
                        });
                } else {
                    var typeParams = {
                        layer: csvLayer,
                        numTypes: 0,
                        field: "ClassName",

                        view: view,
                        legendOptions: {
                            title: "VGS Data Points"
                        }
                    };
                    typeCreatorProxy
                        .createRenderer(typeParams)
                        .then(function (response) {
                            // set the renderer to the layer and add it to the map

                            csvLayer.renderer = {
                                type: "simple", // autocasts as new SimpleRenderer()
                                symbol: {
                                    type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
                                    size: 6,
                                    color: "#0c234b",
                                    outline: { // autocasts as new SimpleLineSymbol()
                                        width: 0.5,
                                        color: "white"
                                    }
                                }
                            };
                            //map.add(csvLayer);

                        })
                        .catch(function (error) {
                            console.error("there was an error: ", error);
                        });


                }


            }

            let map,
                view,
                csvLayer,
                csvLayerView,
                polygonGraphicsLayer,
                sketchViewModel,
                highlight,
                grid,
                legend,
                typeCreatorProxy,
                simpleRendererProxy,
                labelClass;



            function RunMap() {
                require([
                    "esri/Map",
                    "esri/layers/CSVLayer",
                    "esri/views/MapView",
                    "esri/layers/GraphicsLayer",
                    "esri/widgets/Sketch/SketchViewModel",
                    "dgrid/OnDemandGrid",
                    "dgrid/extensions/ColumnHider",
                    "esri/Graphic",
                    "dstore/legacy/StoreAdapter",
                    "dojo/store/Memory",
                    "dgrid/Selection",
                    "esri/core/urlUtils",
                    "esri/layers/FeatureLayer",
                    "esri/PopupTemplate",
                    "esri/widgets/Legend",
                    "esri/renderers/smartMapping/creators/type",
                    "esri/renderers/SimpleRenderer",
                    "esri/symbols/SimpleLineSymbol",
                    "esri/Color",
                    "esri/symbols/SimpleFillSymbol",
                    "esri/widgets/Print",
                    "esri/layers/support/LabelClass",

                    "esri/core/promiseUtils",
                    "dojo/domReady!"
                ],
                    function (Map,
                        CSVLayer,
                        MapView,
                        GraphicsLayer,
                        SketchViewModel,
                        OnDemandGrid,
                        ColumnHider,
                        Graphic,
                        StoreAdapter,
                        Memory,
                        Selection,
                        urlUtils,
                        FeatureLayer,
                        PopupTemplate,
                        Legend,
                        typeRendererCreator,
                        SimpleRenderer,
                        SimpleLineSymbol,
                        Color,
                        SimpleFillSymbol,
                        Print,
                        LabelClass,
                        promiseUtils) {

                        typeCreatorProxy = typeRendererCreator;
                        simpleRendererProxy = new SimpleRenderer();

                        const url = "data.csv";

                        function blankIfUndefined(item) {
                            if (item == undefined) {
                                return "";
                            } else {
                                return item;
                            }
                        }



                        const template_dot = new PopupTemplate(
                            {
                                title: "Site {SiteName}",
                                outfields: ["*"],
                                content: function (data) {
                                    ///debugger;
                                    //  if (data.graphic.attributes.FK_Site == 0) {

                                    var br = document.createElement("DIV");
                                    br.innerHTML = "<br/>";

                                    //site edit icon
                                    var icon = document.createElement("I");
                                    icon.className = 'fa fa-info-circle';
                                    icon.style = 'font-size: 32px;vertical-align:bottom';
                                    icon.title = 'View Site Details';
                                    icon.innerHTML = "&nbsp;";

                                    //site edit url
                                    var siteEditUrl = document.createElement("A");
                                    siteEditUrl.style = 'color:#8b0015';
                                    siteEditUrl.href = "/Containers/viewSite/63448eb6-c585-4f19-9b2c-ae5d5a0c2dc2/" + data.graphic.attributes.PK_SiteClass + "/" + data.graphic.attributes.FK_Site;
                                    siteEditUrl.target = "_new";
                                    siteEditUrl.append(icon);

                                    //report icon
                                    var dashimage = document.createElement("IMG");
                                    dashimage.src="/Content/Images/ReportDash.svg";
                                    dashimage.style = "height:28px";

                                    //report link
                                    var aref = document.createElement("A");
                                    aref.href = "/ReportExport/Dashboard3/63448eb6-c585-4f19-9b2c-ae5d5a0c2dc2/" +
                                        data.graphic.attributes.FK_Site;
                                    //aref.className = "btn btn-default";
                                    aref.target = "_new";
                                    aref.title = "View Report Dashboard";
                                    aref.append(dashimage);

                                    //FOLDER
                                    var div = document.createElement("DIV");
                                    div.append(siteEditUrl);
                                    div.appendChild(aref);
                                    div.appendChild(br);
                                    var folder = document.createElement("DIV");
                                    folder.innerHTML = "<b>Folder:</b> " + data.graphic.attributes.ClassName;
                                    folder.style = "padding-bottom:5px;";
                                    div.appendChild(br);
                                    div.appendChild(folder);


                                    //Date Established
                                    var dateToUse = "" + data.graphic.attributes.Date;
                                    dateToUse = dateToUse.replace("x", "");
                                    var dateEstablished = document.createElement("DIV");
                                    dateEstablished.innerHTML = "<b>Established:</b>" + dateToUse;
                                    dateEstablished.style = "padding-bottom:5px;";
                                    div.appendChild(dateEstablished);


                                    var coordinates = document.createElement("DIV");
                                    coordinates.innerHTML = "<b>Coordinates:</b>  Long: " +
                                        data.graphic.attributes.longitude +
                                        " Lat:" +
                                        data.graphic.attributes.latitude;
                                    coordinates.style = "padding-bottom:5px;";
                                    div.appendChild(coordinates);

                                    var evelation = document.createElement("DIV");
                                    evelation.innerHTML = "<b>Elevation:</b> " + data.graphic.attributes.Elevation;
                                    evelation.style = "padding-bottom:5px;";
                                    div.appendChild(evelation);

                                    var description = document.createElement("DIV");
                                    description.innerHTML = "<b>Description:</b> " + data.graphic.attributes.Description;
                                    div.appendChild(description);


                                    return div;


                                }


                                //content:popupResult



                            });

                        const gridDiv = document.getElementById("grid");
                        const infoDiv = document.getElementById("info");
                        const gridFields = [
                            "__OBJECTID", "latitude", "longitude",
                            "ClassName", "SiteName", "Description"
                        ];
                        const dataStore = new StoreAdapter({
                            objectStore: new Memory({
                                idProperty: "__OBJECTID"
                            })
                        });
                        csvLayer = new CSVLayer({
                            url: url,
                            copyright: "University of Arizona",
                            title: "VGS Data Points",
                            popupTemplate: template_dot,
                            objectIdField: "__OBJECTID",


                        });

                        map = new Map({
                            basemap: "topo",
                            layers: [csvLayer]
                        });

                        view = new MapView({
                            container: "viewDiv",
                            center: [-113.5, 36.7],
                            zoom: 10,
                            map: map
                        });


                        csvLayer.when(function () {
                            const featureLayer = map.layers.getItemAt(0);





                            try {

                                const x = csvLayer.fullExtent.center.x;
                                view.goTo(csvLayer.fullExtent);
                                const queryParams = csvLayer.createQuery();
                                queryParams.geometry = csvLayer.fullExtent;
                                queryParams.where = queryParams.where + " AND  1=1";

                                csvLayer.queryFeatures(queryParams).then(function (results) {


                                    const graphics = results.features;
                                    const data = graphics.map(function (feature, i) {
                                        return Object.keys(feature.attributes)
                                            .filter(function (key) {
                                                // get fields that exist in the grid
                                                return (gridFields.indexOf(key) !== -1);
                                            })
                                            // need to create key value pairs from the feature
                                            // attributes so that info can be displayed in the grid
                                            .reduce(function (obj, key) {
                                                obj[key] = feature.attributes[key];
                                                return obj;
                                            },
                                                {});
                                    });

                                    // set the datastore for the grid using the
                                    // attributes we got for the query results

                                    dataStore.objectStore.data = data;
                                    grid.set("collection", dataStore);

                                });


                            } catch (ex) {

                                window.alert("There are no sites in this folder with locations attached");
                            }
                            createGrid(csvLayer.fields);
                            view.whenLayerView(csvLayer).then(function (layerView) {
                                csvLayerView = layerView;


                            });

                        }).catch(errorCallback);;












                        function selectFeatureFromGrid(event) {
                            // close view popup if it is open

                            view.popup.close();
                            // get the ObjectID value from the clicked row
                            const row = event.rows[0];
                            const id = row.data.__OBJECTID;


                            // setup a query by specifying objectIds
                            const query = {
                                objectIds: [parseInt(id)],
                                outFields: ["*"],
                                returnGeometry: true
                            };

                            // query the csvLayerView using the query set above
                            csvLayerView.queryFeatures(query).then(function (results) {

                                const graphics = results.features;
                                // remove all graphics to make sure no selected graphics
                                view.graphics.removeAll();

                                // create a new selected graphic
                                const selectedGraphic = new Graphic({
                                    geometry: graphics[0].geometry,
                                    symbol: {
                                        type: "simple-marker",
                                        style: "square",
                                        color: "purple",
                                        size: "14px", // pixels
                                        outline: { // autocasts as new SimpleLineSymbol()
                                            color: [255, 255, 0],
                                            width: 2 // points
                                        }
                                    }
                                });

                                // add the selected graphic to the view
                                // this graphic corresponds to the row that was clicked
                                view.graphics.add(selectedGraphic);
                            })
                                .catch(errorCallback);
                        }

                        function createGrid(fields) {

                            const columns = fields.filter(function (field, i) {
                                if (gridFields.indexOf(field.name) !== -1) {
                                    return field;
                                }
                            }).map(function (field) {
                                if (field.name === "__OBJECTID") {
                                    return {
                                        field: field.name,
                                        label: field.name,
                                        sortable: true,
                                        hidden: true
                                    };
                                } else {
                                    return {
                                        field: field.name,
                                        label: field.alias,
                                        sortable: true
                                    };
                                }
                            });

                            // create a new onDemandGrid with its selection and columnhider
                            // extensions. Set the columns of the grid to display attributes
                            // for the layer
                            grid = new (OnDemandGrid.createSubclass([Selection, ColumnHider]))({
                                columns: columns
                            },
                                "grid");

                            // add a row-click listener on the grid. This will be used
                            // to highlight the corresponding feature on the view
                            grid.on("dgrid-select", selectFeatureFromGrid);
                        }



                        function clearUpSelection() {
                            view.graphics.removeAll();
                            //  grid.clearSelection();
                        }

                        function errorCallback(error) {
                            console.log("error:", error);
                        }


                    });
            }

            RunMap();



        </script>


    </div>






<div id="info">
    <!------------- MAP VIEW-->
    <div id="viewDiv" class="col-lg-12" style="height: 800px; width: 100%;">


        <!------------- FILTER BUTTON-->
        <div id="select-by-polygon" class="esri-widget esri-widget--button esri-widget esri-interactive"
             title="Select features by polygon">

            <span class="fas fa-filter"></span>

        </div>




    </div>

    <!----------------------GRID HTML-->

</div>
<br/>
<div id="showAttributesDiv" style="width:100%">
    <div id="gridDisplay">
        <span class="info" id="featureCount"></span>
        <div id="grid"></div>
    </div>
</div>


    <style>
        .navbar-inverse .navbar-nav > li > a {
            color: white;
        }

        .navbar-inverse .navbar-link {
            color: white;
        }

        .navbar-inverse {
            background-color: green;
        }

        .dropdown-menu {
            background-color: green;
        }

        .panel-primary > .panel-heading {
            background-color: green;
            color: white;
        }

        .navbar-toggle {
            background-color: green;
            color: white;
        }


        btn {
            background-color: green;
            color: white;
        }

        input.btn-primary {
            background-color: green;
            color: white;
        }

        button.btn-primary:hover {
            background-color: white color: green;
        }

        input.btn-primary:hover {
            background-color: white color: green;
        }

        button.btn-primary {
            background-color: green;
            color: white;
        }

        input.btn-default {
            background-color: green;
            color: white;
        }

            input.btn-default:hover {
                background-color:;
                white color:green;
            }
    </style>





</body>
</html>

 

I have also included a CSV file in the attachments to duplicate the error.

 

 

 

0 Kudos
1 Solution

Accepted Solutions
UndralBatsukh
Esri Regular Contributor

Hi Don,

OK I looked at your app and thank you for the simple reproducible case. I had to recruit couple my coworkers to figure why it wasn't working especially the first one. I would have never caught it. :grinning_face:

So there are couple of issues in the app. First issue is the following. Notice that outfields has lower case f. You need to change it to outFields.

 

 const template_dot = new PopupTemplate({
    title: "Site {SiteName}",
    outfields: ["*"],
    content: ...
});

 

 

That still did not solve the problem. I narrowed this down to a data issue. CSV file has a field called __ObjectId. This is causing the same issue as the above. To workaround this issue, please rename this field to Id or just remove it. CSVLayer assign objectID to your features. I have created an issue for this. Will let you know once we fix it.

Here is your app in a codepen and is working expected now.

Please do not hesitate to reach out to me if you have more questions.

-Undral

View solution in original post

0 Kudos
5 Replies
UndralBatsukh
Esri Regular Contributor

Hi Don,

OK I looked at your app and thank you for the simple reproducible case. I had to recruit couple my coworkers to figure why it wasn't working especially the first one. I would have never caught it. :grinning_face:

So there are couple of issues in the app. First issue is the following. Notice that outfields has lower case f. You need to change it to outFields.

 

 const template_dot = new PopupTemplate({
    title: "Site {SiteName}",
    outfields: ["*"],
    content: ...
});

 

 

That still did not solve the problem. I narrowed this down to a data issue. CSV file has a field called __ObjectId. This is causing the same issue as the above. To workaround this issue, please rename this field to Id or just remove it. CSVLayer assign objectID to your features. I have created an issue for this. Will let you know once we fix it.

Here is your app in a codepen and is working expected now.

Please do not hesitate to reach out to me if you have more questions.

-Undral

0 Kudos
don-EMerson
New Contributor II

I see the fix worked in the demo. I have moved to the real page (which is way more complex) and it doesn't seem to do multiple items in the popup template no matter how far I zoom back. So it is fixed, a little odd, but fixed. 

Thank you

0 Kudos
UndralBatsukh
Esri Regular Contributor

Have you deleted the objectId column from the csv file you are using for the real site? Once I deleted it the column, I started seeing the multiple items.

0 Kudos
don-EMerson
New Contributor II

Yea, I did it all. It is just I can't get the original multiple popup templates to happen ever. So technically I can't test the solution because I can't do the conditions but I am calling it good. I was able to get rid of all the code that was calling back to the database to get items past that first template in my actual application. So in my mind, mission accomplished. 

0 Kudos
UndralBatsukh
Esri Regular Contributor

Hi there,

I just want to give you a quick on this. We fixed this issue at JS API version 4.22. This version will be released end of December. The popup will display for all overlapping features without you having to do anything once you migrate to 4.22.

 

Thanks,

-Undral

0 Kudos