AMD confusion about parser.parse

4895
10
05-22-2015 09:43 AM
SteveCole
Frequent Contributor

I'm jumping off the deep end and starting to convert some apps to AMD style that were originally written in legacy dojo. One thing I've picked up about migrating to AMD is that the legacy practice of doing this:

<script type ="text/javascript">
var dojoConfig = {parseOnLoad: true};
</script>

in the HTML header section has been replaced by doing this:

ready(function() {
     parser.parse();
     .....
}

down in the Javascript code. I never questioned this; I just did it. In my current work trying to migrate a legacy app to AMD, I ran into a maddening issue where my attempts to establish a listener event on a dojo form that had two radio checkboxes as choices:

// Event listener to enable/disable controls based on the input method chosen
dijit.byId("frmEndMethod").on('change', function() {
....
});

would always error out because dijit.byId() couldn't find the widget and thus, returned undefined. The code was within the ready(function() {...}); so it should have no problems finding it. In fact, I could type "dijit.byId("frmEndMethod")" into the console after page load and it does return the dijit. No matter what I tried, I could not get this to work. Then I reverted back the the legacy variable declaration in the header and commented out parser.parse() in my JS code.

Surprise, surprise- it loaded without error and the event now triggers. So what gives? Am I "wrong" to still use the dojoConfig variable with AMD style coding? I mean, it seems to work, which is the whole point but is there something I'm missing?

Steve

0 Kudos
10 Replies
TimWitt2
MVP Alum

Hey Steve,

If you don't mind, I changed this into a question.

Tim

0 Kudos
TimWitt2
MVP Alum

You did include in your require([ "dojo/parser"] and in your function the corresponding parser right?

i.e.

require(["dojo/parser"], function (parser) {

     parser.parse();

0 Kudos
SteveCole
Frequent Contributor

No problem changing it to a question. I saw it as a discussion but no big deal.

Yes- I do have parser specified in my list of requires.

0 Kudos
thejuskambi
Occasional Contributor III

I believe it is the first thing you need to call before all the other dijits and widgets initialization.

There are many ways to setup the dojo config

you can use the legacy way like this

<script>
  dojoConfig= {
  parseOnLoad: false,
   async: true
  };

</script>

of use script tag

<script src="http://js.arcgis.com/3.13/ " data-dojo-config="parseOnLoad: false,  async: 1">
</script>

Read more here:

Configuring Dojo with dojoConfig - Dojo Toolkit Tutorial

0 Kudos
SteveCole
Frequent Contributor

In my code, when I was trying to use parser.parse(), it was my first line of code in my ready() function.

0 Kudos
thejuskambi
Occasional Contributor III

What is this ready function?. Can you share the code. It should be as Tim shown below require

0 Kudos
SteveCole
Frequent Contributor

Sorry- the ready function as in dojo/ready:

require([
    "dojo/ready",
    "dojo/on",
    "dojo/_base/connect",
    "dojo/_base/event",   
    "dojo/dom",
    "dojo/fx",
    "dojox/grid/DataGrid",   
    "dgrid/Selection",
    "dojo/promise/all",
    "dojo/data/ItemFileReadStore",   
    "dojo/store/Memory",
    "dojo/_base/array",   
    "dijit/registry",
    "dojo/_base/declare",
    "dojo/dom-construct",
    "dojo/keys",
    "dojo/parser",
    "dijit/form/Button",
    "dijit/form/CheckBox",
    "dijit/form/DateTextBox",
    "dijit/form/FilteringSelect",
    "dijit/form/Form",   
    "dijit/form/Select",
    "dijit/form/HorizontalSlider",
    "dijit/form/HorizontalRule",
    "dijit/form/RadioButton",
    "dijit/form/TextBox",
    "dijit/form/TimeTextBox",
    "dijit/layout/BorderContainer",
    "dijit/layout/ContentPane",
    "dojox/layout/ExpandoPane",
    "dijit/layout/AccordionContainer",
    "dijit/Menu",
    "dijit/MenuItem",
    "dijit/MenuSeparator",
    "esri/Color",
    "esri/geometry/Extent",
    "esri/geometry/webMercatorUtils",
    "esri/graphic",
    "esri/InfoTemplate",
    "esri/map",
    "esri/arcgis/utils",
    "esri/domUtils",
    "esri/dijit/Geocoder",   
    "esri/dijit/HomeButton",
    "esri/dijit/BasemapToggle",
    "esri/dijit/Measurement",   
    "esri/dijit/Popup",
    "esri/dijit/PopupTemplate",
    "esri/geometry/Point",
    "esri/SpatialReference",
    "esri/symbols/SimpleLineSymbol",
    "esri/symbols/SimpleMarkerSymbol",
    "esri/symbols/SimpleFillSymbol",
    "esri/symbols/PictureMarkerSymbol",
    "esri/layers/FeatureLayer",
    "esri/layers/GraphicsLayer",
    "esri/toolbars/draw",
    "esri/tasks/FeatureSet",
    "esri/tasks/GeometryService",
    "esri/tasks/locator",
    "esri/tasks/ProjectParameters",
    "esri/tasks/query",
    "esri/tasks/QueryTask",   
    "esri/tasks/RouteParameters",   
    "esri/tasks/query"
], function(
    ready,
    on,
    connect,
    event,
    dom,
    fx,
    DataGrid,   
    Selection,
    all,   
    ItemFileReadStore,
    Memory,
    array,
    registry,
    declare,
    domConstruct,
    keys,
    parser,
    Button,
    CheckBox,
    DateTextBox,
    FilteringSelect,
    Form,
    Select,
    HorizontalSlider,
    HorizontalRule,
    RadioButton,
    TextBox,
    TimeTextBox,
    BorderContainer,
    ContentPane,
    ExpandoPane,
    AccordionContainer,
    Menu,
    MenuItem,
    MenuSeparator,
    Color,
    Extent,
    webMercatorUtils,
    Graphic,
    InfoTemplate,
    Map,
    arcgisUtils,
    domUtils,
    Geocoder,
    HomeButton,
    BasemapToggle,
    Measurement,
    Popup,
    PopupTemplate,
    Point,
    SpatialReference,
    SimpleLineSymbol,
    SimpleMarkerSymbol,
    SimpleFillSymbol,
    PictureMarkerSymbol,
    FeatureLayer,
    GraphicsLayer,
    Draw,
    FeatureSet,
    GeometryService,
    Locator,
    ProjectParameters,
    Query,
    QueryTask,
    RouteParameters,
    Query
) {
    ready(function(){
        parser.parse();

        esri.config.defaults.io.proxyUrl = "http://dmc-arcgis/proxy/proxy.ashx";
        esri.config.defaults.io.alwaysUseProxy = false;
       //etc..etc..etc..
       dijit.byId("cboRdName").on('change', function(selection) {
                updateCrossStreetList();
                closureProps['rdName'] = document.getElementById('cboRdName').value;
                closureProps['status'] ='CLOSED';
                zoomToRoad();
       });
  }
0 Kudos
thejuskambi
Occasional Contributor III

Try to move the parser.parse outside the ready function. As per the doc dojo/ready — The Dojo Toolkit - Reference Guide  it says, its has been replaced by AMD API. so you dont exactly need to use ready  unless there is a special requirement.

I also see you are loading a huge list of objects in the require. try to avoid it, load only the ones you are going to use are used in Html. I understand you are migrating from legacy to AMD style. try to be more modulaized and divide the code into smaller modules and widgets. Hope it was helpful.

KenBuja
MVP Esteemed Contributor

Instead of using dijit.byId, have you tried using registry.byId?

0 Kudos