AnsweredAssumed Answered

How do I use the "this./lang.hitch" correctly in Custom WAB DE widget?

Question asked by agelfert on Jan 29, 2020
Latest reply on Jan 30, 2020 by agelfert

Okay, I'm venturing into somewhat new terrain here... I've read countless examples providing various levels of clarity on the subject but I'm banging my head against the wall trying to make my example work.

 

After working through a few easy examples of custom widget for Web AppBuilder and successfully interacting with map and layers, etc. I wanted to try and bring in some of the JSAPI modules.

Objective: hook a dom input field up to event listener/handler that executes a query against a map service. After a few circuitous failed attempts, I settled for trying to adapt this ESRI example: 

https://developers.arcgis.com/javascript/3/jshelp/intro_querytask.html.

 

In my imports I have the following:

define(['dojo/_base/declare', 
'jimu/BaseWidget',
'dijit/_WidgetsInTemplateMixin',     //The Mixin is like my MultiVitamin.
                                     //Not sure I need it here but I've
                                     //needed in the past and learned the hard way.

'esri/tasks/QueryTask',  //query and QueryTask (watch for upper/lower case!)
'esri/tasks/query',      //are needed for the query.

"dojo/_base/lang",       //to hitch a lang

"dojo/on",               //"On" and "dom" I'm using for the event handling.
"dojo/dom"],

  function(declare,
    BaseWidget,
    _WidgetsInTemplateMixin,
    QueryTask,
    Query,
    lang,
    on,
    dom)

 

My template code all follows the Custom Widget template, so I won't include here. All my custom code I packed in the onOpen lifecycle function, starting with:

 

onOpen: function(){
   this.inherited(arguments);  // Dont' know if I really need this - do I?
   console.log('onOpen');
          
   var searchBtn = dom.byId('searchBtn');
   on(searchBtn,"click",function(evt){
   lang.hitch(this,lang.hitch(this,executeQueryTask()));   // Just my last attempt...
   });

So this handles the input event. Next I set up my query:

var query = new Query();
query.returnGeometry = false;
query.outFields = ["NAME"];  // Any field will do right now
 
queryUrl = "https:// ... this is the URL to my service ends in ....MapServer/0";
var queryTask = new QueryTask({queryUrl});

Finally, simplifying the above ESRI example. I set up three (3) functions:

  1. Reads the current input in the DOM field.
  2. Executes the query using the JS API.
  3. Displays the results passed from 2) and print record count to the console.
    function showResults(featureSet) {
       var resultFeaturesCount = featureSet.features.length;
       console.log(resultFeaturesCount);
       }
         
    function getInput(){
       return document.getElementById('searchField').value; 
       }
           
    function executeQueryTask() {
       query.where = `NAME like '%${getInput()}%'`
       queryTask.execute(query,showResults);
       }

So I think I understand what I'm trying to do. My widget looks great. My event handler works. But the error has been the same all along:

Uncaught TypeError: Cannot read property 'query' of undefined
    at Object.execute (init.js:2315)
    at Object.c.<computed> [as execute] (init.js:1148)
    at executeQueryTask (Widget.js?wab_dv=2.14:101)
    at HTMLInputElement.<anonymous> (Widget.js?wab_dv=2.14:67)

Everything I've read (most of it by our generous contributor Robert Scheitlin, GISP) leads me to believe this is all about scope. So what am I missing? The scope-hitch-lang still confuses me.

Outcomes