Select to view content in your preferred language

Want to create a module for this QueryTask functionality

4788
26
Jump to solution
08-10-2015 02:29 PM
TracySchloss
Frequent Contributor

I have two external tables that contain an ID and a description.  They are the basis for a set of menus, and since they are very similar in their schema, I'm attempting to create one tool  for creating an array of code and description pairs.  In addition, I'm using this as a learning tool for defining modules and it's not going so well. These these will eventually be input for menus, as well as look

These are two different tables and the field names are not  identical, so I need to account for that as well.

In my Map module, myMap.js, I have defined this variable, which is a table I have loaded as a featureLayer, along with several other layers.

        var specUrl = specialtyTable.url;

added a listener for the map load event:

myPopulateCodeList.populateCode('spec',specUrl);

The function populateCode is getting called, but I need to keep the codeList array as a variable, because I'll use it again in more than one place.

myPopulateCodeList.js

 define([
  "dojo/on", 
  "esri/tasks/QueryTask", 
  "esri/tasks/query"
  ], function(
  on,QueryTask, Query){
  var codeList = [];
      return {
        populateCode: function(codeType, url){
          switch (codeType) {
            case "spec":
              codeAtt = 'ID_SPECIALTY_PK';
              specAtt = 'TX_SPECIALTY_DESC';
              break;
            default:
              codeAtt = 'ID_PROV_TYPE_PK';
              specAtt = 'TX_PROV_DESC';
              break;
          }
          var queryTask = new QueryTask(url);
          var query = new Query();
          query.outFields = ["*"];
          query.where = "1=1";
          query.returnGeometry = false;
          on(queryTask, 'complete', this.codeResultsHandler);
          on(queryTask, 'error', this.errorHandler);
          queryTask.execute(query);
        },
        
        //builds codeList object containing codes and descriptions 
        codeResultsHandler: function(results){
          var numResults = results.featureSet.features.length;         
            for (var j = 0; j < numResults; j++) {
              var code = results.featureSet.features.attributes[codeAtt];
              var desc = results.featureSet.features.attributes[specAtt];
              codeList.push({
                code: code,
                desc: desc
              });
            }
            console.log('end of codeList array build');
            return codeList;
          },
        
        errorHandler: function(err){
          console.log("error in myPopulateCodeList, error: " + err.details);
        }
        
      }
    return codeList;
     
    });

I can see that codeList is getting populated with values from the results handler of the queryTask, but I can't figure out how to pass this result back to the calling function.  This doesn't work:

var specCodeList = myPopulateCodeList.populateCode('spec',specUrl);

When I had it all in one big file, this was working, but I'm trying to learn how to break my work up into smaller bits.

0 Kudos
26 Replies
TracySchloss
Frequent Contributor

I supposed the lines connecting the posts are supposed to help us, but they really don't.  And you're right, two different Robert's doesn't help alleviate the confusion. 

I'm not finding that app is available to the rest of my modules.  It seems like sometimes I see

app = {}; and other times app = [];

I'm defining it with curly braces.  It seems like it should be a generic object, not an array. 

When I attempt to use it in another module that needs the codeList I just saved as app.specCodeList, it says it 'app' is not defined.

0 Kudos
RobertWinterbottom
Occasional Contributor

depends where you are defining app.  If you are defining app in a module you could try window.app = {};  then everywhere else in the code you can refer to it as app.  If you define app in a module, it will be local to the module since define wraps the whole module.

for example,

define([], function () {

  // Anything defined anywhere in here only exists in here

  // If you return app as a property, then you can reuse it but then anyone who wants it must require this module

  // However, below would allow anyone in the program to access it.

  window.app = {};

});

TracySchloss
Frequent Contributor

I defined it in my index.html as window.app = {} and now I can just reference my two code lists as app.codeList1 and app.codeList2 in my other modules. 

RobertWinterbottom
Occasional Contributor

Yup you got it

0 Kudos
SteveCole
Frequent Contributor

FWIW, this link is what I originally found when researching global variables and Javascript. It turns out the curly braces are the proper way; I don't know how I mangled it to be brackets! Oddly enough, brackets still work in my applications. Oh well.

Glad you got it all sorted out!

Steve

0 Kudos
TracySchloss
Frequent Contributor

Well that piece of it anyway.  I've been hesitant to show my ignorance of how to write proper AMD style, but I decided I wasn't the only one who is confused.  I feel like all the examples are either 'hello world' level or broken into so many bits that I lose track of how it all fits together.  There's not nearly enough transitional type examples to suit me.

0 Kudos
RobertWinterbottom
Occasional Contributor

You are exactly right Tracy.  We had a lot of difficulties where I work with this transition as well for the exact same reason.  We even wrote some really ugly and unmaintainable code during that period, but after a month or two it kind of just clicks and then it gets much easier, but organizing it is always a difficult thing to figure out.  Some things I've learned when moving to AMD are:

  1. Keep things simple, don't go module crazy right out of the gate and try to mimic what you see where an app has 100's of tiny modules, you'll get there eventually, larger modules make things easy during the transition but they are less maintainable.
  2. Using something like window.app = {} to store commonly shared variables or data will be a life saver, we still use this today at my workplace in almost every app.
  3. Spend some time learning what the difference between returning a Class or returning an object that contains some methods.  Knowing when the appropriate time to use a Class vs a plain old object can be a lifesaver.
  4. Learn the dojoConfig.  You will inevitably hit some multipleDefine errors which will possibly make you question your career choice with the lack of information/help around this issue.  dojoConfig has some special options that will prevent this issue if you use it correctly. (such as aliases which will let you load jQuery through AMD instead of a global script tag, which is one of the most common causes of this error)
0 Kudos