Inconsistency in Map popup and popup actions

06-27-2023 06:31 AM
New Contributor


Th inbuilt actions supported for the popup/popupTemplate are inconsistent, I keep seeing new action items on the popup each time. Even in the examples provided on the arcgis API documentation i see new popup actions most of the time. We use the same in our project too and see new options coming up sometimes even without updating the arcgis library versions. Any reason why this happens?

I see an option to remove the actions using view.popup.viewModel.includeDefaultActions = false;

But is there a way to keep the actions consistent and have only zoom to and cluster features "1 of X" action for a popup template on a GeoJSONLayer as marked in the below screenshot.



Please kindly suggest on this at the earliest.

0 Kudos
2 Replies
Esri Contributor

Hi @ThanmaiC -

By default, the only action added to a popup in the JS SDK is the "Zoom to" action button (noted here). The feature pagination (arrows and feature menu button) shows up if you select an area in the map that has overlapping features. If feature reduction is enabled on the layer and it has a popup template, the "Browse features" action will appear as well. 

Could you provide an example application where you see other actions appearing in the popup by default? 

0 Kudos
New Contributor

My code looks something like this

const loadCurrentMap = () => {

    const { mapData, selectedPage, footerSize, actualFullArr } = this.state;

    // create a new blob from geojson featurecollection

    const blob = new Blob([JSON.stringify(mapData)], {

      type: "application/json",


    // URL reference to the blob

    const url = URL.createObjectURL(blob);

    const layer = new GeoJSONLayer({

      title: "Properties",

      url: url,

      outFields: ["*"],

      // popupTemplates can still be viewed on

      // individual features

      popupTemplate: {

        title: "",


          "{propName}, Area {area}  Rent {rent} Availabilities {noOfAvail}",

        overwriteActions: true,


      renderer: {

        type: "simple",

        field: "mag",

        symbol: {

          type: "picture-marker",

          url: mapMarker,

          height: 16,

          width: 14.5,

          xoffset: 0,

          yoffset: 0,

          outline: {

            width: 2,

            color: "#ffffff",





    const graphicsLayer = new GraphicsLayer();

    const map = new Map({

      basemap: this.props.baseMap,

      layers: [graphicsLayer, layer],


    console.log("resultCoord", resultCoord);

    var extent = new Extent({

      xmin: resultCoord[0],

      ymin: resultCoord[1],

      xmax: resultCoord[2],

      ymax: resultCoord[3],

      spatialReference: {

        wkid: 4326,



    const view = new MapView({

      container: "mapContainer123",

      map: map,

      //   zoom: 12,

      extent: extent.expand(2),


    const home = new Home({

      view: view,


    const sketch = new Sketch({

      layer: graphicsLayer,

      view: view,

      snappingOptions: {

        // autocasts to SnappingOptions()

        enabled: true, // global snapping is turned on

        // assigns a collection of FeatureSnappingLayerSource() and enables feature snapping on this layer

        featureSources: [{ layer: graphicsLayer, enabled: true }],


      creationMode: "single",


    sketch.visibleElements = {

      createTools: {

        point: false,

        polyline: false,


      selectionTools: {

        "lasso-selection": false,

        "rectangle-selection": false,


      settingsMenu: false,


    // Listen to sketch widget's create event.

    sketch.on("create", function (event) {

      // check if the create event's state has changed to complete indicating

      // the graphic create operation is completed.

      if (event.state === "active") {

        // to allow only one sketch drawn at a time and delete older ones




      if (event.state === "complete") {

        // on sketch complete thake the extent and calculate it to show/zoom the screen to that region

        // rings provides the boundaries of the shape drawn

        // use the boundaries and loop over the mapData array to check if any pin lies inside those boundary.

        // using turf function to find if its inside

        const geom = event.graphic.geometry;

        // console.log("geom", geom, geom.extent);

        let extent1 = new Extent({

          xmin: geom.extent.xmin,

          ymin: geom.extent.ymin,

          xmax: geom.extent.xmax,

          ymax: geom.extent.ymax,



        // rings is the outer boundaries of the plotted shape

        let rings = geom && geom.rings;

        if (rings && rings.length > 0) {

          console.log("rings", rings, rings.length);

            // Do some filtering




    // to set the widgets on the map view

    view.ui.add(sketch, {

      position: "manual",


    view.ui.move("zoom", "bottom-right");

    // to remove unwanted options buttons in popup

    // view.popup.autoOpenEnabled = false;

    // view.popup.viewModel.includeDefaultActions = false;

    view.popup.dockOptions = {

      buttonEnabled: false,


    view.whenLayerView(layer).then((lv) => {

      const layerView = lv;    
const customContentPromise = new CustomContent({
        outFields: ["*"],
        creator: (event) => {
          const query = layerView.createQuery();
          query.aggregateIds = [event.graphic.getObjectId()];
          console.log("query", query);
          return layerView.queryFeatures(query).then((result) => {
            console.log("result.features", result.features);
            const contentDiv = document.createElement("div");
            const featuresUl = document.createElement("ul");
            let featureLi;
            for (const feature of result.features) {
              featureLi = document.createElement("li");
              featureLi.innerText = `Properties ${feature.attributes.propName} ${feature.attributes.area} ${} ${feature.attributes.noOfAvail}`;
            return contentDiv;

      const clusterConfig = {

        type: "cluster",

        clusterRadius: "100px", //100

        // {cluster_count} is an aggregate field containing the number of features comprised by the cluster

        popupTemplate: {

          title: "This Area Contains {cluster_count} results",

          outFields: ["*"],

          content: [customContentPromise],

          actions: [],


        clusterMinSize: "24px", //24

        clusterMaxSize: "60px", //60

        labelingInfo: [


            deconflictionStrategy: "none",

            labelExpressionInfo: {

              expression: "Text($feature.cluster_count, '#,###')",


            symbol: {

              type: "text",

              color: "#ffffff",

              font: {

                weight: "bold",

                family: "Noto Sans",

                style: "normal",

                size: "12px",



            labelPlacement: "center-center",




      layer.featureReduction = clusterConfig;



I am using a GeoJSON layer for the purpose of clustering and my pop up with this piece of code is as below:


As in the screenshot I see the Browse features coming up newly.

When i use this line all the actions Zoom to and Browse Features is removed.
view.popup.viewModel.includeDefaultActions = false
So now my questions are:
1.) Is there a way to have only Zoom to option and not Broswe features?
2.) In place of Browse Features is there a option to show the feature pagination (arrows with feature number) just like this: 



3.Also is there a way to find which pins belong to which cluster on the map.

I tried query methods on the GeoJSON Layer but it just returns the data based on the query where clause for that pin and doesnt tell to which cluster ID it belongs to. But I need to know which pins belong to which cluster to open a individual popup of only that property.

My cluster JSON:

export const newSampleLatLong = {

  type: "FeatureCollection",

  features: [


      type: "Feature",

      id: "1",

      properties: {

        propName: "ABC",

        area: "-",

        rent: "-",     

        opentooltip: false,


      geometry: {

        type: "Point",

        coordinates: [77.60539, 12.96625],





Please kindly suggest on this at the earliest.


0 Kudos