My first attempt at creating a widget for web app builder.
Trying to incorporate a pattern where the symbols are defined and referenced in the config.json file.
I am able to create the in-panel widget, add it to apps and run it using a test config. All is well, interacts with the map after clicking a button.
The problem I am having is referencing to a simple marker symbol defined in the config.json file which looks like this:
I can add a graphic to the map at the mouse-click point is I define the symbol in code like this:
symbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_DIAMOND, 10, null, new Color("#ff6666") );
however if I try this:
symbol = new SimpleMarkerSymbol(this.config.symbols.smsymbol);
I get nothing on the map.
Thanks
Solved! Go to Solution.
Keith,
So your issue is one that trips up many JS developers at first, it is a scope issue.
You are trying to use "this" in a function for the draw end and inside that function "this" is different than what "this" is outside of that function. In Dojo you use lang.hitch to get around this issue.
define([ 'dojo/_base/declare', 'jimu/BaseWidget', 'esri/symbols/SimpleMarkerSymbol', 'esri/graphic', 'esri/toolbars/draw', 'esri/Color', 'esri/symbols/SimpleLineSymbol', 'dojo/_base/lang'], function (declare, BaseWidget, SimpleMarkerSymbol, Graphic, Draw, Color, SimpleLineSymbol, lang) { var myDraw, symbol, graphic; //To create a widget, you need to derive from BaseWidget. return declare([BaseWidget], { // Custom widget code goes here baseClass: 'my-first-widget', // this property is set by the framework when widget is loaded. // name: 'MyFirstWidget', // add additional properties here //methods to communication with app container: postCreate: function () { this.inherited(arguments); //console.log('MyFirstWidget::postCreate'); //console.log(this.map.id); }, starting: function () { myDraw.activate(Draw.POINT); //myDraw.activate(Draw.POINT); //console.log('MyFirstWidget::startup'); }, startup: function () { this.inherited(arguments); myDraw = new Draw(this.map); myDraw.on("draw-end", lang.hitch(this, function (evt) { //symbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_DIAMOND, 10, null, new Color("#ff6666") ); symbol = new SimpleMarkerSymbol(this.config.symbols.smsymbol); graphic = new Graphic(evt.geometry, symbol); this.map.graphics.add(graphic); myDraw.finishDrawing(); myDraw.deactivate(); })); }, // onOpen: function(){ // console.log('MyFirstWidget::onOpen'); // }, onClose: function () { myDraw.deactivate(); // console.log('MyFirstWidget::onClose'); } }); });
Keith,
What does the console log look like after you try to draw on the map?
To access your console log/ developer tools right click and click and developer tools.
I am receiving the following:
Uncaught TypeError: Cannot read property 'symbols' of undefined
Keith,
Are you sure that you are getting json when you use this.config.symbols.smsymbol?
I have this in my config.json
"simplemarkersymbol": { "color": [255, 255, 255, 64], "size": 12, "type": "esriSMS", "style": "esriSMSDiamond", "outline": { "color": [0, 0, 0, 255], "width": 1, "type": "esriSLS", "style": "esriSLSSolid" } },
and this in my widget.js
symbol = new SimpleMarkerSymbol(this.config.symbols.simplemarkersymbol);
and it works fine. Are there any errors in your web console?
Thanks Robert.
I am receiving the following:
Uncaught TypeError: Cannot read property 'symbols' of undefined
Keith,
So that is saying that this.config is undefined. Is there anywhere else in your code that you are reading values from the config that are working? You may be trying to read the config in the wrong spot. I need to see your widget.js
Keith,
So your issue is one that trips up many JS developers at first, it is a scope issue.
You are trying to use "this" in a function for the draw end and inside that function "this" is different than what "this" is outside of that function. In Dojo you use lang.hitch to get around this issue.
define([ 'dojo/_base/declare', 'jimu/BaseWidget', 'esri/symbols/SimpleMarkerSymbol', 'esri/graphic', 'esri/toolbars/draw', 'esri/Color', 'esri/symbols/SimpleLineSymbol', 'dojo/_base/lang'], function (declare, BaseWidget, SimpleMarkerSymbol, Graphic, Draw, Color, SimpleLineSymbol, lang) { var myDraw, symbol, graphic; //To create a widget, you need to derive from BaseWidget. return declare([BaseWidget], { // Custom widget code goes here baseClass: 'my-first-widget', // this property is set by the framework when widget is loaded. // name: 'MyFirstWidget', // add additional properties here //methods to communication with app container: postCreate: function () { this.inherited(arguments); //console.log('MyFirstWidget::postCreate'); //console.log(this.map.id); }, starting: function () { myDraw.activate(Draw.POINT); //myDraw.activate(Draw.POINT); //console.log('MyFirstWidget::startup'); }, startup: function () { this.inherited(arguments); myDraw = new Draw(this.map); myDraw.on("draw-end", lang.hitch(this, function (evt) { //symbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_DIAMOND, 10, null, new Color("#ff6666") ); symbol = new SimpleMarkerSymbol(this.config.symbols.smsymbol); graphic = new Graphic(evt.geometry, symbol); this.map.graphics.add(graphic); myDraw.finishDrawing(); myDraw.deactivate(); })); }, // onOpen: function(){ // console.log('MyFirstWidget::onOpen'); // }, onClose: function () { myDraw.deactivate(); // console.log('MyFirstWidget::onClose'); } }); });
That was it exactly.
I appreciate your time Robert.