Add a Graphic to Web Map in WAB

700
12
Jump to solution
12-19-2018 09:29 AM
michael_vetter
Occasional Contributor

I'm trying to create a custom WAB widget that shows the locations of restaurants that are within a mile radius from an address that the user enters. I'm using the Yelp API through an esriRequest call. The results contain that lat/long of the restaurants. These lat/long values are what I want to use for the location of the graphics. It appears that creating the graphic is successful, but when I use this.map.graphics.add(graphic) I get an error message of init.js:114 TypeError: Cannot read property 'add' of undefined

Any help would be greatly appreciated!

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Esteemed Contributor

Michael,

  The issue I see right up front is (line 19):

//Create a function to get the Yelp businesses
    _getYelp: function(x,y){
      // var map = this.map;
      var food = esriRequest({
        url: "https://api.yelp.com/v3/businesses/search",
        content: {
          f: "json",
          latitude: x,
          longitude: y,
          radius: 1610,
          sort_by: "distance",
          categories: "restaurants, All"
        },
        handleAs: "json",
        headers: {
          "Authorization": "Bearer "
        }
      });
      food.then(lang.hitch(this, function(response){
        console.log(response);
        var i;
        for (i = 0; i <= 10; i++){
          $(".name" +[i]).append(response.businesses[""+[i]+""].name);
          $(".price" +[i]).append(response.businesses[""+[i]+""].price);
          $(".rating" +[i]).append(response.businesses[""+[i]+""].rating);
          var x1 = response.businesses[""+[i]+""].coordinates.longitude;
          var y1 = response.businesses[""+[i]+""].coordinates.latitude;
          $(".link"+[i]).attr("href", "https://www.google.com/maps/place/"+y1+","+x1);
          var markerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE,50, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([26,26,26])),new Color([26,26,26]));
          var pt = new esri.geometry.Point({"x":x1, "y":y1, "spatialReference":{wkid:4326}});
          var graphic = new esri.Graphic(pt,markerSymbol);
          this.map.graphics.add(graphic);
        }
      }), function(error){
        console.log(error);
      });
    },

View solution in original post

12 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

Michael,

  Sounds like it could be a scope issue but It is hard to tell without seeing your code.

0 Kudos
michael_vetter
Occasional Contributor

Sorry about that. I've attached my Widget.js file for the widget, but I took out the Yelp API key.

Thanks for your help!

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Michael,

  The issue I see right up front is (line 19):

//Create a function to get the Yelp businesses
    _getYelp: function(x,y){
      // var map = this.map;
      var food = esriRequest({
        url: "https://api.yelp.com/v3/businesses/search",
        content: {
          f: "json",
          latitude: x,
          longitude: y,
          radius: 1610,
          sort_by: "distance",
          categories: "restaurants, All"
        },
        handleAs: "json",
        headers: {
          "Authorization": "Bearer "
        }
      });
      food.then(lang.hitch(this, function(response){
        console.log(response);
        var i;
        for (i = 0; i <= 10; i++){
          $(".name" +[i]).append(response.businesses[""+[i]+""].name);
          $(".price" +[i]).append(response.businesses[""+[i]+""].price);
          $(".rating" +[i]).append(response.businesses[""+[i]+""].rating);
          var x1 = response.businesses[""+[i]+""].coordinates.longitude;
          var y1 = response.businesses[""+[i]+""].coordinates.latitude;
          $(".link"+[i]).attr("href", "https://www.google.com/maps/place/"+y1+","+x1);
          var markerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE,50, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([26,26,26])),new Color([26,26,26]));
          var pt = new esri.geometry.Point({"x":x1, "y":y1, "spatialReference":{wkid:4326}});
          var graphic = new esri.Graphic(pt,markerSymbol);
          this.map.graphics.add(graphic);
        }
      }), function(error){
        console.log(error);
      });
    },

View solution in original post

michael_vetter
Occasional Contributor

Robert,

I added the lang.hitch function to the code and now I'm getting this error: TypeError: lang.hitch is not a function

I do have 'dojo/_base/lang' in the define portion of the file.

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Michael,

  So that is because you have an issue in your define array and subsequent vars.

define(['dojo/_base/declare',
  'jimu/BaseWidget',
  './idWebMapLayers',
  'esri/dijit/Search',
  'esri/request',
  'dojo/on',
  'dojo/dom-construct',
  './files/jquery-3.3.1.min',
  './yelp',
  './ResultDisplay',
  "esri/config",
  "esri/geometry/Point",
  "esri/symbols/SimpleMarkerSymbol",
  "esri/symbols/SimpleLineSymbol",
  "esri/Color",
  "esri/graphic",
  "esri/layers/GraphicsLayer",
  "esri/SpatialReference",
  "dojo/_base/lang",
  "dojo/domReady!"
],
function(declare, BaseWidget, idWebMapLayers, Search, esriRequest, on, domConstruct, Yelp, ResultDisplay, esriConfig, Point, SimpleMarkerSymbol, SimpleLineSymbol, Color, Graphic, GraphicsLayer, SpatialReference, lang) {

You have './files/jquery-3.3.1.min', in the array and do not have a matching function var. Are you even using jquery? if not just remove './files/jquery-3.3.1.min',

0 Kudos
michael_vetter
Occasional Contributor

Robert,

Removing './files/jquery-3.3.1.min' fixed the problem. Now if I wanted to have the results to be exportable by the user, would the ideal way of accomplishing this be to create a graphics layer and then create a feature layer from the graphics layer? Or is there a way to create a feature layer from graphics?

Thanks again for all the help!

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Michael,

Creating a FeatureLayer from a collection of graphics is the way to go and is covered in this sample:

Feature collection | ArcGIS API for JavaScript 3.27 

0 Kudos
michael_vetter
Occasional Contributor

Robert,

I took a look at the sample and modified my code to match the sample. When I run the widget, a feature layer does get added to the map; however, nothing gets displayed on the map and the attribute says there's one record, but there are no attributes for that record.  Here's what I've done based on the sample:

//Create a feature collection which will form the new feature layer
      var featureCollection ={
        "layerDefinition": null,
        "featureSet": {
          "features": [],
          "geometryType": "esriGeometryPoint"
        }
      };
      featureCollection.layerDefinition = {
        "geometryType": "esriGeometryPoint",
        "drawingInfo": {
          "renderer": {
            "type": "simple",
            "symbol": {
              "color": [210,105,30,191],
              "size": 6,
              "type": "esriSMS",
              "style": "esriSMSCircle",
              "outline": {
                "color": [0,0,128,255],
                "width": 0,
                "type": "esriSLS",
                "style": "esriSLSSolid"
              }
            }
          }
        },
        "fields": [{
          "name": "Name",
          "alias": "Name",
          "type": "esriFieldTypeString"
        },{
          "name": "Price",
          "alias": "Price",
          "type": "esriFieldTypeString"
        },{
          "name": "Rating",
          "alias": "Rating",
          "type": "esriFieldTypeString"
        }]
      };

      this.featureLayer = new FeatureLayer(featureCollection, {
        id: "Restaurants"
      });

      food.then(lang.hitch(this, function(response){
        var i;
        var features = [];
        for (i = 0; i <= 10; i++){
          var name = response.businesses[""+[i]+""].name;
          var price = response.businesses[""+[i]+""].price;
          var rating = response.businesses[""+[i]+""].rating;
          var x1 = response.businesses[""+[i]+""].coordinates.longitude;
          var y1 = response.businesses[""+[i]+""].coordinates.latitude;
          var markerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE,10, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([26,26,26])),new Color([26,26,26]));
          var pt = new esri.geometry.Point({"x":x1, "y":y1, "spatialReference":{wkid:4326}});
          var attr = {"Name":name, "Price":price, "Rating":rating};
          var infoTemplate = new InfoTemplate("Restaurants Near Searched Address","Restaurant Name: ${Name}<br/>Price: ${Price}<br/>Rating: ${Rating}");
          var graphic = new esri.Graphic(pt,markerSymbol,attr, infoTemplate);
          // this.map.graphics.add(graphic);
          features.push(graphic);
        }
        this.featureLayer.add(features);
        this.map.addLayer(this.featureLayer);
      }), function(error){
        console.log(error);
      });
    }

Thanks,

Michael

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Michael,

   Based on that sample it should be:

this.featureLayer.applyEdits(features, null, null);

Not

this.featureLayer.add(features);

the add method on a FeatureLayer is for One graphic not an array of graphics.

0 Kudos