ArcGIS Esri – Popup template custom content not showing graphic attributes. (Angular 11)

0

Issue

I’m going to display a customContent in arcgis popup template in Angular 11 application. But the value of graphic.attributes is not coming to the innerText. In console log I can see the graphic objects are coming as expected. But it’s showing undefined for grahpic.attributes Can anyone help with to solve this issue?

            new CustomContent({
    outFields: ["*"],
    creator: (eventOrGraphic) => {
        const graphic = eventOrGraphic instanceof Graphic ? eventOrGraphic : eventOrGraphic.graphic;
        const a = document.createElement("a");
        a.href = graphic.attributes.url;
        a.target = "_blank";
        a.innerText = graphic.attributes.url;
        return a;
    }
})

Console.log(eventOrGraphic)

graphic: p
destroy: ƒ value()
initialize: ƒ value()
uid: 1474
__accessor__: g {host: p, properties: Map(8), ctorArgs: null, destroyed: false, lifecycle: 2, …}
attributes: (...)    
geometry: (...)
isAggregate: (...)
layer: (...)
popupTemplate: (...)
sourceLayer: (...)
symbol: (...)
visible: (...)
[[Prototype]]: Object

Console.log(graphic.attributes) – undefined

arcgis-js-api(4.2.1)

Solution

Ok, so it seems that the parameter of CustomContent creator function is of the form {graphic: Graphic}.

The never error is because not type was assigned, so you can assign any to actually avoid it. I am not exactly sure of the correct type.

This is the key part of the example,

new CustomContent({
  outFields: ["*"],
  creator: (event: any) => {
    console.log(event.graphic);
    const a = document.createElement("a");
    a.href = event.graphic.attributes.url;
    a.target = "_blank";
    a.innerText = event.graphic.attributes.url;
    console.log(event.graphic.attributes.url);
    return a;
  }
})

This is the whole example,

app.component.ts

import {
  Component,
  OnInit,
  OnDestroy,
  ElementRef,
  ViewChild
} from '@angular/core';

import ArcGISMap from '@arcgis/core/Map';
import Graphic from '@arcgis/core/Graphic';
import MapView from '@arcgis/core/views/MapView';
import FeatureLayer from '@arcgis/core/layers/FeatureLayer';
import Collection from "@arcgis/core/core/Collection";
import CustomContent from '@arcgis/core/popup/content/CustomContent';
import PopupTemplate from '@arcgis/core/PopupTemplate';
import SimpleRenderer from "@arcgis/core/renderers/SimpleRenderer";
import TextSymbol from "@arcgis/core/symbols/TextSymbol";
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit, OnDestroy {
  @ViewChild('mapViewNode', { static: true }) private mapViewEl!: ElementRef;
  public view: any = null;

  initializeMap(): Promise<any> {
    const container = this.mapViewEl.nativeElement;

    const map = new ArcGISMap({
      basemap: "streets-navigation-vector"
    });

    const view = new MapView({
      container: container,
      map: map,
      zoom: 12,
      center: { type: 'point', x: -117.1490, y: 32.7353 }
    });

    const popupTemplate = new PopupTemplate({
      title: "{name}",
      content: [
        {
          type: "fields",
          fieldInfos: [
            {
              fieldName: "addrs",
              label: "Address"
            },
            {
              fieldName: "lat",
              label: "Latitude",
              format: {
                places: 2
              }
            },
            {
              fieldName: "lon",
              label: "Longitude",
              format: {
                places: 2
              }
            }
          ]
        },
        new CustomContent({
          outFields: ["*"],
          creator: (event: any) => {
            console.log(event.graphic);
            const a = document.createElement("a");
            a.href = event.graphic.attributes.url;
            a.target = "_blank";
            a.innerText = event.graphic.attributes.url;
            console.log(event.graphic.attributes.url);
            return a;
          }
        })
      ],
      outFields: ["*"]
    });
    const data = [
      {
        lat: 32.727482,
        lon: -117.1560632,
        name: "Automotive Museum",
        addrs: "2080 Pan American Plaza, San Diego, CA 92101, United States",
        url: "http://sdautomuseum.org/"
      },
      {
        lat: 32.7136902,
        lon: -117.1763293,
        name: "USS Midway Museum",
        addrs: "910 N Harbor Dr, San Diego, CA 92101, United States",
        url: "http://www.midway.org/"
      },
      {
        lat: 32.7641112,
        lon: -117.2284536,
        name: "SeaWorld",
        addrs: "500 Sea World Dr, San Diego, CA 92109, United States",
        url: "https://seaworld.com/san-diego"
      },
      {
        lat: 32.7360032,
        lon: -117.1557741,
        name: "Zoo",
        addrs: "2920 Zoo Dr, San Diego, CA 92101, United States",
        url: "https://zoo.sandiegozoo.org/"
      }
    ];
    const layer = new FeatureLayer({
      source: new Collection(data.map((d, i) => (
        {
          geometry: {
            type: "point",
            longitude: d.lon,
            latitude: d.lat
          },
          attributes: {
            ObjectID: i,
            ...d
          }
        }
      ))),
      fields: [
        {
          name: "ObjectID",
          alias: "ObjectID",
          type: "oid"
        },
        {
          name: "name",
          alias: "Name",
          type: "string"
        },
        {
          name: "addrs",
          alias: "addrs",
          type: "string"
        },
        {
          name: "url",
          alias: "url",
          type: "string"
        },
        {
          name: "lat",
          alias: "Latitude",
          type: "double"
        },
        {
          name: "lon",
          alias: "Longitude",
          type: "double"
        },
      ],
      objectIdField: "ObjectID",
      geometryType: "point",
      renderer: new SimpleRenderer({
        symbol: new TextSymbol({
          color: "red",
          text: "\ue61d",
          font: {
            size: 30,
            family: "CalciteWebCoreIcons"
          }
        })
      }),
      popupTemplate
    });

    map.add(layer);
    this.view = view;
    return this.view.when();
  }

  ngOnInit(): any {
    this.initializeMap().then(() => {
      console.log('The map is ready.');
    });
  }

  ngOnDestroy(): void {
    if (this.view) {
      this.view.destroy();
    }
  }
}

app.component.html

<div #mapViewNode></div>

app.component.scss

@import 'https://js.arcgis.com/4.22/@arcgis/core/assets/esri/themes/light/main.css';
.esri-view {
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
}
#mapViewNode {
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
}

styles.scss

html,
body {
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
}

Answered By – cabesuon

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave A Reply

Your email address will not be published.

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More