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!
Solved! Go to Solution.
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);
});
},
Michael,
Sounds like it could be a scope issue but It is hard to tell without seeing your code.
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);
});
},
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.
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',
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!
Michael,
Creating a FeatureLayer from a collection of graphics is the way to go and is covered in this sample:
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
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.