Select to view content in your preferred language

Registry Error in Custom Widget

2315
26
Jump to solution
01-24-2018 07:53 AM
AbhinavSharma
New Contributor III

//Updated define //

//updated last line from fields to fieldNames// 

Hi everyone, I am attempting to expand my widget by adding in a renderer that is is available to the end user. I have been working my way through the following ESRI Sample. The sample is for a mapservice and not a feature layer but I do not see why the same idea can not be applied. The issue is in bold. It stops at both of those instances. I have used console.log to see if there is any difference in the object that is being passed. ( Looked at the object in the sample and compared to my own) and the only difference i can find is when i print out fieldname after the push: using (console.log("fieldnames", fieldNames)

the sample looks like this:

fieldnames

  1. {identifier: "value", label: "name", items: Array(2)}
    1. identifier:"value"
    2. items:Array(10)
      1. 0:
        1. name:["FIPS"]
        2. value:["FIPS"]
        3. _0:0
        4. _RI:true
        5. _S:{_arrayOfAllItems: Array(10), _arrayOfTopLevelItems: Array(10), _loadFinished: true, _jsonFileUrl: undefined, _ccUrl: undefined, …}
        6. __proto__:Object 

whereas from my widget it looks like this:

fieldnames

  1. {identifier: "value", label: "name", items: Array(1)}
    1. identifier:"value"
    2. items:Array(19)
      1. 0:
        1. name:"OBJECTID"
        2. value:"OBJECTID"

TypeError: Cannot read property 'on' of undefined

define(
['dojo/_base/declare',
'jimu/BaseWidget',
"esri/toolbars/draw",
"esri/toolbars/edit",
"esri/graphic",
"esri/request",
"esri/config",
"esri/tasks/ClassBreaksDefinition",
"esri/tasks/UniqueValueDefinition",
"esri/tasks/AlgorithmicColorRamp",
"esri/tasks/GenerateRendererParameters",
"esri/tasks/GenerateRendererTask",
"esri/layers/LayerDrawingOptions",
"esri/layers/FeatureLayer",
"esri/layers/Field",
"esri/symbols/SimpleMarkerSymbol",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleFillSymbol",
"esri/dijit/editing/TemplatePicker",
"dojo/_base/array",
"dojo/_base/event",
"dojo/_base/lang",
"dojo/parser",
"dijit/registry",
"dojo/data/ItemFileReadStore",
"dojox/grid/DataGrid",
"dijit/form/FilteringSelect",
"dojo/domReady!"],
function(declare, BaseWidget, Draw, Edit, Graphic, esriRequest, esriConfig,
 ClassBreaksDefinition, UniqueValueDefinition, AlgorithmicColorRamp,
 GenerateRendererParameters, GenerateRendererTask, LayerDrawingOptions,
 FeatureLayer,Field,
 SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol,
 TemplatePicker,
 arrayUtils, event, lang, parser, registry, ItemFileReadStore, DataGrid, FilteringSelect) {
 //To create a widget, you need to derive from BaseWidget.
 return declare([BaseWidget], {
 // DemoWidget code goes here
//please note that this property is be set by the framework when widget is loaded.
 //templateString: template,
baseClass: 'jimu-widget-ROP',
postCreate: function() {
 this.inherited(arguments);
 console.log('postCreate');
 },
startup: function() {
 ///INICIO/////
 parser.parse();
// refer to "Using the Proxy Page" for more information: https://developers.arcgis.com/javascript/3/jshelp/ags_proxy.html
 esriConfig.defaults.io.proxyUrl = "/proxy/";
 map= this.map;
map.on("layers-add-result", initEditing);

 var landusePolygonLayer = new FeatureLayer("MyLayer", {
 id: "canada_Risk",//confirm works
 mode: FeatureLayer.MODE_ONDEMAND,
 outFields: ["*"]
 });
 console.log("LayerInfo", landusePolygonLayer)
 map.addLayers([landusePolygonLayer]);
//fieldInfo
 var canadaFields = esriRequest({
 url:"https://services7.arcgis.com/Layer",
 content:{
 f: "json"
 },
 callbackParamName : "callback"
 });
 console.log("fields", canadaFields)
 canadaFields.then(function(resp){
 var fieldNames, fieldStore;
fieldNames = { identifier : "value", label: "name", items: []};
 console.log("fields", fieldNames)
 arrayUtils.forEach(resp.fields,function(f){
 fieldNames.items.push({"name": f.name, "value": f.name});
 console.log("fieldnames", fieldNames)
 });
fieldStore = new ItemFileReadStore({ data:fieldNames});
 console.log("store", fieldStore)
 registry.byId("fieldNames").set("store", fieldStore);
 }, function(err){
 console.log("failed to get field names: ", err);
 });
 //update when field name changes
 registry.byId("fieldNames").on("change", getData);
0 Kudos
26 Replies
AbhinavSharma
New Contributor III

Well that was stupid of me. I am now getting  TypeError: Cannot read property 'set' of undefined from the line: 

this.sourceLayerFieldSelect.set("value", f.name)
0 Kudos
KenBuja
MVP Esteemed Contributor

What is the name of your dijit? You're using the name from my example, but from your html you posted earlier, should it be

this.fieldNames.set("value", f.name)

If that's not the case, then post your html code.

0 Kudos
AbhinavSharma
New Contributor III

I actually added both 

<div class="jimu-widget-use-jquery">
Use ctrl or cmd + click on graphic to delete.  Double click on graphic to edit vertices.
<div id="templatePickerDiv"></div>
<label for="fieldNames">Render based on: </label>
            <select id="fieldNames" name="baseSym"
                    data-dojo-type="dijit/form/FilteringSelect"
                    data-dojo-props="style:'width:200px;'">
            </select>
<div data-dojo-attach-point="sourceLayerFieldSelect" class="esriCTDownloadTabTextbox" data-dojo-type="dijit/form/Select"
  data-dojo-props='required:true,trim:true,disabled:true' /div>

</div>
0 Kudos
KenBuja
MVP Esteemed Contributor

There's an additional thing I overlooked. I think you have to add in the module 'dijit/_WidgetsInTemplateMixin' and the associated argument '_WidgetsInTemplateMixin' and declare your widget like this

return declare([BaseWidget, _WidgetsInTemplateMixin], {‍

It's recommended the BaseWidget and mixin modules are added at the beginning of the array

0 Kudos
AbhinavSharma
New Contributor III

I am still getting the same error 

TypeError: Cannot read property 'set' of undefined 


 I tried just calling sourceLayerFieldSelect but got a reference error, even though this is the id in the widget.html. Maybe it is not being set properly? 

0 Kudos
KenBuja
MVP Esteemed Contributor

Can you zip up the widget's file and post them?

0 Kudos
AbhinavSharma
New Contributor III

Sure is just the widget.html and widget.js fine? I attached it below.

0 Kudos
KenBuja
MVP Esteemed Contributor

Boiling it down to its simplest, this shows how to make a Select dijit in your Widget, add items to it, and see what gets selected. You were missing a closing bracket on the div and the opening bracket in the /div in the html

Widget.html

<div>
  <div data-dojo-attach-point="sourceLayerFieldSelect" data-dojo-type="dijit/form/Select"
       data-dojo-props='required:true,trim:true,disabled:true'>
  </div>
</div>

Widget.js

define(['dojo/_base/declare', 'jimu/BaseWidget', 'dijit/_WidgetsInTemplateMixin', 'jimu/dijit/Message', 'dojo/on', 'dojo/_base/lang', 'dijit/form/Select'], function (declare, BaseWidget, _WidgetsInTemplateMixin, Message, on, lang) {
  return declare([BaseWidget, _WidgetsInTemplateMixin], {

    // Custom widget code goes here

    baseClass: 'testing',
    _featureLayer: null,

    postCreate: function postCreate() {
      this.inherited(arguments);
      console.log('Testing::postCreate');
      this._initDijits();
    },

    _initDijits: function _initDijits() {

      var option = [{
        value: 'Field_1',
        label: 'Field 1'
      }, {
        value: 'Field_2',
        label: 'Field 2'
      }, {
        value: 'Field_3',
        label: 'Field 3'
      }];
      this.sourceLayerFieldSelect.addOption(option);
      this.sourceLayerFieldSelect.set('disabled', false);
      this.own(on(this.sourceLayerFieldSelect, 'change', lang.hitch(this, this._onFieldSelectChange)));
    },

    _onFieldSelectChange: function _onFieldSelectChange() {
      new Message({
        titleLabel: 'Field Selected',
        message: 'Selected ' + this.sourceLayerFieldSelect.get('value')
      });
    }
  });
});
0 Kudos
AbhinavSharma
New Contributor III

dijit.form.Select — The Dojo Toolkit - Reference Guide  I decided to follow this guide (namely the select by a store one) and I think the problem is with the way my data is being created. when viewed in the chrome console my data (data) will look like the following 

I created field names how i have been doing before but now am using this method to create the form:

var data = fieldNames.items;
        console.log("data", data)

        var store = new Memory({
          data: [data]
        });
        var os = new ObjectStore({objectStore: store});

        var s = new Select({
          store: os
        }, "sourceLayerFieldSelect");
        s.startup();
        console.log(s)

and am calling it the same as i was before in widget.html

<label for="sourceLayerFieldSelect">Render based on: </label>
<div data-dojo-attach-point="sourceLayerFieldSelect"  data-dojo-type="dijit/form/Select"
  data-dojo-props='required:true,trim:true,disabled:true' >
</div>
</div>

the weird part is that now I do not get any errors the dropdown menu just does not display any values inside of my widget.

0 Kudos
KenBuja
MVP Esteemed Contributor

Instead of lines 9-12, try

this.sourceLayerFieldSelect.store(os);‍

The data array may need "value" and "label" instead of "value" and "name"

0 Kudos