Select to view content in your preferred language

Cannot read property 'call' of undefined

3820
4
Jump to solution
05-22-2018 12:40 PM
ElizabethMiller
Regular Contributor

My custom widget has a click event handler that works with a draw toolbar and a dojo deferred function to create a snapped point on a map. The tool is working well with no errors in functionality in the map but I am getting a console error that I can't get rid of. I can't figure out what is causing it. The error occurs after the console.log('end') and before the console.log('second end') (see code snippet below). Can anyone help me troubleshoot the cause of this error so I can get rid of it? Here is the error:

Uncaught TypeError: Cannot read property 'call' of undefined
at Object.<anonymous> (init.js:653)
at Object.c [as onClick] (init.js:119)
at Object._fire (init.js:1299)
at Object._fireClickEvent (init.js:1306)
at init.js:63
(anonymous) @ init.js:653
c @ init.js:119
_fire @ init.js:1299
_fireClickEvent @ init.js:1306
(anonymous) @ init.js:63
setTimeout (async)
_onClickHandler @ init.js:1305
(anonymous) @ init.js:63

Here is my code:

addtoMap: function(evt){

 
this.own(this.defmapClickEvtHandler = this.map.on("click", lang.hitch(this, function(evt){
 
this.map.graphics.clear();
 
var deferred = this.map.snappingManager.getSnappingPoint(evt.screenPoint);
 
var sms = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_DIAMOND, 12,
 new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([70, 0, 130, 1]), 1), new Color([70, 0, 130, 1]));
 
deferred.then(lang.hitch(this, function(value){
 
 var point;
 
 if (value !== undefined){
 point = value;
 
 } else {
 point = evt.mapPoint;
 
 } 
 
 var graphic = new Graphic(point, sms);
 
 this.map.graphics.add(graphic);
 
},
 
));
console.log('end');
 
 })));

console.log('second end');     
},
     
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Elizabeth,

   So based on your code you call createToolbar every time you click on the map after you toggle your button. Then you add another map click event listener in the addtoMap function. So basically you now have two functions listening for a map click and one of them continues to add more listeners each time the map is clicked. This is not a good workflow.  It would seem more appropriate for your toggleGTM to call the createToolbar directly instead of adding a map click event listener to call it.

View solution in original post

4 Replies
RobertScheitlin__GISP
MVP Emeritus

Elizabeth,

   There is nothing that stands out in your code as an error. What does the function that calls addtoMap look like?

0 Kudos
ElizabethMiller
Regular Contributor

OK Robert, here goes, here is more of my code, hope it's not too bad! As I said, it functions well right now in the map. Thank you for your attention.

Elizabeth

return declare([BaseWidget, _WidgetsInTemplateMixin], {
baseClass: 'jimu-widget-mywidget',
 name: 'mywidget',
 
 gtoolbar: [],
postCreate: function() {
 this.inherited(arguments);
 console.log('postCreate');
 
 },

startup: function() {
 this.inherited(arguments); 
 
 },

toggleGTM: function () {
 
 if (this.toggleButton.label == 'Tool Stopped'){
 this.toggleButton.set('label', 'Tool Started');
 this.toggleButton.set('baseClass', 'success');
 this.map.setMapCursor('crosshair');
 this.own(this.mapClickEvtHandler = this.map.on("click", lang.hitch(this.createToolbar())));
 
 
 } else if (this.toggleButton.label == 'Tool Started'){
 this.toggleButton.set('baseClass', 'danger');
 this.toggleButton.set('label', 'Tool Stopped');
 this.map.setMapCursor('default');
 this.mapClickEvtHandler.remove();
 this.defmapClickEvtHandler.remove();
 this.onClose();
 
 
 }
 },
 
 
 createToolbar: function(){
 
 var trunkHwys = new FeatureLayer("http://myurl/FeatureServer/0",
 {
 mode: FeatureLayer.MODE_ONDEMAND,
 outFields: ["*"]
 });
 this.map.addLayers([trunkHwys]);
 
 var snapManager = this.map.enableSnapping({
 tolerance: 30,
 alwaysSnap: true
 });
 
 
 var layerInfos = [{
 layer: trunkHwys
 }];
 
 snapManager.setLayerInfos(layerInfos); 
 
 this.gtoolbar = new Draw(this.map);
 this.gtoolbar.activate(Draw["POINT"]);
 
 this.addtoMap();
},
 
addtoMap: function(){
 
 var geometryLocation;
 
 geometryLocation = "";
 
 this.own(this.defmapClickEvtHandler = this.map.on("click", lang.hitch(this, function(evt){
 
 this.map.graphics.clear();
 
 this.gtoolbar.activate(Draw["POINT"]);
var deferred = this.map.snappingManager.getSnappingPoint(evt.screenPoint);
 
 var sms = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_DIAMOND, 12,
 new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([70, 0, 130, 1]), 1), new Color([70, 0, 130, 1]));
 
 deferred.then(lang.hitch(this, function(value){
 
 var point;
 
 if (value !== undefined){
 point = value;
 
 } else {
 point = evt.mapPoint;
 
 } 
 
 var graphic = new Graphic(point, sms);
 
 this.map.graphics.add(graphic);
geometryLocation = {
 'geometry': {
 /* 'x': evt.mapPoint.x,
 'y': evt.mapPoint.y */
 'x': point.x,
 'y': point.y
 }
 };
},
 
 ));
 
 console.log('end');
 this.anotherfunction(geometryLocation);
 })));
 
//here is where the error occurs -- before 'second end'

 console.log('second end');
 
 },
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Elizabeth,

   So based on your code you call createToolbar every time you click on the map after you toggle your button. Then you add another map click event listener in the addtoMap function. So basically you now have two functions listening for a map click and one of them continues to add more listeners each time the map is clicked. This is not a good workflow.  It would seem more appropriate for your toggleGTM to call the createToolbar directly instead of adding a map click event listener to call it.

ElizabethMiller
Regular Contributor

I think that did it! Thank you!

I made the following changes to the toggleGTM:

toggleGTM: function () {
 
 if (this.toggleButton.label == 'Tool Stopped'){
 this.toggleButton.set('label', 'Tool Started');
 this.toggleButton.set('baseClass', 'success');
 this.map.setMapCursor('crosshair');
 //this.own(this.mapClickEvtHandler = this.map.on("click", lang.hitch(this.createToolbar())));
 this.createToolbar();
 
 
 } else if (this.toggleButton.label == 'Tool Started'){
 this.toggleButton.set('baseClass', 'danger');
 this.toggleButton.set('label', 'Tool Stopped');
 this.map.setMapCursor('default');
 //this.mapClickEvtHandler.remove();
 this.defmapClickEvtHandler.remove();
 this.gtoolbar.deactivate();
 this.onClose();
 
 
 }
 },
0 Kudos