I have a series of graphics that get added to a single graphics layer when a user toggles on a switch. There are different toggles for each graphic (they're routes to bus lines) but all route graphics are being added to the same graphics layer. When a user toggles off a certain route, I want the route to be removed from the graphics layer, but keep the other routes on the graphics layers if they're toggled on. I have assigned the graphic being added a unique ID, however, using graphicsLayerName.remove(graphicID) isn't working for me.
//create graphic layer
app.routesGraphicsLayer = new GraphicsLayer({
id:'routesGraphicsLayer'
])
//Add graphics layer
app.map.addLayer(app.routesGraphicsLayer)
app.routesGraphicsLayer.hide() //will get shown when toggled on
//Create unique variable names for graphic IDs
var redRoute;
//When Toggled ON:
app.handleLayerVis = function (switchName, state) {
require(["dojo/dom","dojo/dom-class","dojox/mobile/Switch"], function(dom,domClass,Switch){
console.log(switchName + " -- " + state);
if (state === "on") {
console.log('app.showLoading()');
app.showLoading();
}
//hide popup
if (state === "off") {
app.map.infoWindow.hide();
}
switch (switchName) {
case "redShuttleSwitch":
if (state === "on") {
//Turn off All Active Shuttles if its currently toggled on
app.switchLogic();
//Request Route
app.esriRouteRequest(15).then(function (routeResponse) {
app.routesGraphicFunction("Red", routeResponse, app.routesGraphicsLayer, redRoute);
//Display route
app.showGraphicsLayer('routesGraphicsLayer');
});
else {
//when route gets toggled off, remove graphic from graphics layer
app.routesGraphicsLayer.remove(redRoute);
app.routesGraphicsLayer.redraw();
}
break;
app.esriRouteRequest = function() {
var routeRequest = new esriRequest({
url: "http://www.uofubus.com/Services/JSONPRelay.svc/GetRoutesForMapWithScheduleWithEncodedLine",
content: {
apikey: "ride1791",
},
handleAs: "json",
callbackParamName: "method"
});
routeRequest.then(app.routeRequestSucceeded, app.requestFailed);
return routeRequest;
}
app.routeRequestSucceeded = function(data) {
routesArray = [];
for (i = 0; i < data.length; i++) {
routesArray.push(data[i]);
}
return routesArray;
}
app.routesGraphicFunction = function (colorDescription, data, graphicslayer, routeGraphic) {
var routeObjects = data;
for (i = 0; i < routeObjects.length; i++) {
if (routeObjects[i].Description == colorDescription){
//Create Symbology
var routeSLS = new SimpleLineSymbol ().setStyle(SimpleLineSymbol.STYLE_SOLID).setWidth(4).setColor(new Color(routeObjects[i].MapLineColor));
//Create InfoTemplate
var routesInfoTemplate = new InfoTemplate (routeObjects[i].Description+" Line", "<b>Stops Schedule: </b>" + app.moreInfoHyperlink(routeObjects[i].StopTimesPDFLink))
//Create Graphic
routeGraphic = new Graphic(new Polyline(app.decodeGooglePolyline(routeObjects[i].EncodedPolyline), app.map.SpatialReference), routeSLS, routeObjects[i].StopTimesPDFLink, routesInfoTemplate);
}
}
//Add graphics to graphics layer
graphicslayer.add(routeGraphic);
}
Solved! Go to Solution.
R,
You loop through the GraphicsLayer.graphics and look at each graphic for the unique Id.
R.
So a GraphicsLayer.remove is expecting to be based a Graphic (not an Id), so is redRoute an actual graphic?
app.routesGraphicsLayer.remove(redRoute);
Robert -
My intention is that it is but I must be doing this incorrectly.
In my app.routesGraphicFunction (line 66), at the very end of the function I create a new Graphic (line 76).
in the function, rather than assigning a variable to the new graphic, I assign an argument that can be passed into the function with the idea that the argument value is the unique id. So in this example, when I call the app.routesGraphicFunction, I pass the argument redRoute as the new graphic variable.
'redRoute' was already defined as a global variable on line 11.
What is an alternative for identifying a unique graphic?
R,
You loop through the GraphicsLayer.graphics and look at each graphic for the unique Id.
Thanks Robert - that visually does what I need, but I am getting errors in the console which is leading me to believe that I may be doing something that's going to come back to bite me.
I wrote in an app.removeGraphics function (see below) that loops through the graphics layer and identifies a graphic based on a graphic attribute. IF=f that attribute is there, the graphic is removed. When I toggle one line on and off the graphic clears and no errors are logged to the console. However, when I have 2 or more toggled turned on, the routes still are removed when toggled off, but I get an error in the console. I tried logging the graphicsLayer.graphics properties to the console directly after and new line gets toggled on and then again once a line gets toggled off and then removed. The logs beforehand loos as expected, but when I toggle off a line a get an empty array back even though there is still at least one graphic left visible on the graphics layer.
Error:
main.js:2446 Uncaught TypeError: Cannot read property 'attributes' of undefined
New function:
app.removeGraphic = function (graphicsLayer, description){ for (gL = 0; graphicsLayer.graphics.length; gL++){ if (graphicsLayer.graphics[gL].attributes[0] == description){ graphicsLayer.remove(graphicsLayer.graphics[gL]); graphicsLayer.redraw(); } } }
R,
If you are going to remove items that you are looping though them you need to loop though in reverse (i.e. gl--).
Robert -
I get a similar outcome, except, I now get the same error if I only toggle one layer on then off.
app.removeGraphic = function (graphicsLayer, description){ for (gL = graphicsLayer.graphics.length; gL>0; gL--){ if (graphicsLayer.graphics[gL].attributes[0] == description){ graphicsLayer.remove(graphicsLayer.graphics[gL]); //graphicsLayer.redraw(); } } }
I also tried it with
(gL = graphicsLayer.graphics.length-1
but then the graphic wasn't removed
R,
The
gl = graphicsLayer.graphics.length -1
is the correct way.
So when you add these graphics they only have on attribute? Have you debugged this app and placed a break point in the for loop to see if
graphicsLayer.graphics[gL].attributes[0]
is what you are expecting it to be?
Robert - Yes, I've been doing some console logs and breakpoints. I solved the issue by changing
for (gL = graphicsLayer.graphics.length; gL>0; gL--){
to
gL>=0
Now all graphics get removed when expected and no errors. Thank you.