Select to view content in your preferred language

Seperate JS files

3407
12
Jump to solution
01-31-2018 06:43 AM
jaykapalczynski
Honored Contributor

I have an app that is starting to get a rather large amount of JS.

I was wondering if I could start to separate certain bits of code in a separate JS file and then just reference them.

If I reference it in HTML as I do the main JS file I get errors saying the map is not defined.

<script src="js/index.js"></script>
<script src="js/elevationprofile.js"></script>

Is there a way to reference all the split out JS files in the main JS file?

0 Kudos
1 Solution

Accepted Solutions
KenBuja
MVP Esteemed Contributor

So if I comment out almost all of the requires, leaving

require([
   "esri/map", "esri/geometry/webMercatorUtils", "dojo/dom", "dojo/parser",//"esri/dijit/Legend", //"esri/symbols/SimpleFillSymbol",
    //      "esri/geometry/Extent", "esri/layers/ArcGISDynamicMapServiceLayer", 'esri/layers/WMSLayer', 'esri/layers/WMSLayerInfo', "esri/layers/ImageParameters",
    //      "dojo/_base/array", "dojo/on", "esri/graphic", "esri/graphicsUtils", "esri/tasks/Geoprocessor", "esri/tasks/FeatureSet", "esri/tasks/LinearUnit", "esri/symbols/SimpleLineSymbol",
    //      "esri/renderers/SimpleRenderer", "esri/symbols/SimpleMarkerSymbol", "esri/layers/LabelClass", "esri/dijit/BasemapToggle", "esri/dijit/HomeButton", "esri/dijit/Search", "esri/dijit/LocateButton",
    //    "esri/urlUtils", "esri/dijit/Directions",
    //      "esri/toolbars/draw", "esri/symbols/CartographicLineSymbol", "esri/units", "esri/dijit/ElevationProfile",
    //      "esri/Color", "dojo/_base/array",  "esri/InfoTemplate", "esri/renderers/ClassBreaksRenderer", "dijit/form/CheckBox", "dojo/dom-construct",
    //      "dojo/keys", "esri/SnappingManager", "esri/dijit/Measurement", "esri/tasks/GeometryService", "esri/config", "esri/sniff", "esri/dijit/BasemapGallery",
    //      "esri/layers/LabelLayer", "esri/symbols/TextSymbol", "esri/symbols/Font", "esri/symbols/SimpleLineSymbol",
    //    "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dijit/layout/AccordionContainer", "esri/dijit/Scalebar", "dijit/TitlePane", "dojo/domReady!"
 "dojo/domReady!"
], function (Map, webMercatorUtils, dom, parser
    //Map, webMercatorUtils, dom, FeatureLayer, Legend, SimpleFillSymbol,
    //  Extent, ArcGISDynamicMapServiceLayer, WMSLayer, WMSLayerInfo, ImageParameters,
    //  array, on, Graphic, graphicsUtils, Geoprocessor, FeatureSet, LinearUnit, SimpleLineSymbol,
    //  SimpleRenderer, SimpleMarkerSymbol, LabelClass, BasemapToggle, HomeButton, Search, LocateButton,
    //urlUtils, Directions,
    //  Draw, CartographicLineSymbol, Units, ElevationsProfileWidget,
    //  Color, arrayUtils, parser, InfoTemplate, ClassBreaksRenderer, CheckBox, domConstruct,
    //  keys, SnappingManager, Measurement, GeometryService, esriConfig, has, BasemapGallery,
    //  LabelLayer, TextSymbol, Font, SimpleLineSymbol
      ) {‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

then the code works. If I uncomment the next module, "esri/layers/FeatureLayer", then the code fails. The time it takes to load all those modules was causing a problem. To fix that, I used dom/ready on the other js file. This makes

require(["dojo/ready", "esri/map", "dojo/domReady!"], function (ready, Map) {
    ready(function () {
        map.on("click", function (e) {
            alert("clicked");
        });
    });
});‍‍‍‍‍‍‍‍‍‍‍‍‍‍

From the documentation

dojo/ready registers a function to run when the DOM is ready and all outstanding require() calls have been resolved, and other registered functions with a higher priority have completed.

View solution in original post

12 Replies
jaykapalczynski
Honored Contributor

I tried this:

Added this to HTML under my main js file

<script src="js/index.js"></script>
<!-- New reference to js file  -->
<script src="js/elevationprofile.js"></script> ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

<!-- SNIP -->

<div id="map" class="shadow" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="region:'center'" style="height:100%">     
    <div id="LocateButton" data-dojo-props="region:'center'"></div>     
     <div id="HomeButton"></div>  
     <div id="search"></div>
        <div id="profilecontainer" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'bottom'" >
     <div id="profileChartNode"></div>
    </div>
</div> 

Added this new js file

require([ 
     "esri/map","dojo/domReady!"
], function(
     Map
) {

    map.on("click", function(e){
        alert("clicked");
    });

});‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I get this error:

init.js:28 Uncaught TypeError: map.on is not a function
    at elevationprofile.js:7
    at ia (init.js:28)
    at init.js:28
    at ja (init.js:28)
    at ga (init.js:28)
    at f (init.js:30)
    at HTMLScriptElement.<anonymous> (init.js:35)‍‍‍‍‍‍‍‍
0 Kudos
KenBuja
MVP Esteemed Contributor

Where are you setting a reference to "map"?

0 Kudos
jaykapalczynski
Honored Contributor

I'm not in the 2nd js file...I was following this example towards the bottom.  They dont set the reference in the 2nd js file as I can see.

creating javascript external file for map function 

confused.

I am doing so in the main js file

var map = new Map("map", {
  basemap: "gray",
  center: [-79.665, 37.629],
  zoom: 8,
  logo: false,
  showLabels : true
});
0 Kudos
KenBuja
MVP Esteemed Contributor

If you look at the other example, it declares "map" outside the require section in the first js file. You're declaring it inside.

var map;
require(["esri/map", "dojo/domReady!"],function(Map) {
  map = new Map("map", {
    basemap: "topo",
    center: [-122.45, 37.75], // longitude, latitude
    zoom: 13
  });
});
jaykapalczynski
Honored Contributor

Yea thats what I am doing....in the original js file

      require([
        "esri/map", "esri/geometry/webMercatorUtils", "dojo/dom", "esri/layers/FeatureLayer", "esri/dijit/Legend","esri/symbols/SimpleFillSymbol", 
          "esri/geometry/Extent", "esri/layers/ArcGISDynamicMapServiceLayer", 'esri/layers/WMSLayer', 'esri/layers/WMSLayerInfo', "esri/layers/ImageParameters",
          "dojo/_base/array", "dojo/on", "esri/graphic","esri/graphicsUtils","esri/tasks/Geoprocessor","esri/tasks/FeatureSet","esri/tasks/LinearUnit","esri/symbols/SimpleLineSymbol",
          "esri/renderers/SimpleRenderer", "esri/symbols/SimpleMarkerSymbol","esri/layers/LabelClass", "esri/dijit/BasemapToggle","esri/dijit/HomeButton", "esri/dijit/Search", "esri/dijit/LocateButton",
        "esri/urlUtils", "esri/dijit/Directions",
          "esri/toolbars/draw","esri/symbols/CartographicLineSymbol","esri/units","esri/dijit/ElevationProfile",
          "esri/Color", "dojo/_base/array", "dojo/parser", "esri/InfoTemplate", "esri/renderers/ClassBreaksRenderer","dijit/form/CheckBox", "dojo/dom-construct",       
          "dojo/keys","esri/SnappingManager","esri/dijit/Measurement","esri/tasks/GeometryService","esri/config",     "esri/sniff","esri/dijit/BasemapGallery",     
          "esri/layers/LabelLayer", "esri/symbols/TextSymbol", "esri/symbols/Font", "esri/symbols/SimpleLineSymbol", 
        "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dijit/layout/AccordionContainer","esri/dijit/Scalebar","dijit/TitlePane", "dojo/domReady!"
      ], function(
        Map, webMercatorUtils, dom, FeatureLayer, Legend, SimpleFillSymbol, 
          Extent, ArcGISDynamicMapServiceLayer, WMSLayer, WMSLayerInfo, ImageParameters,
          array, on, Graphic, graphicsUtils, Geoprocessor, FeatureSet, LinearUnit, SimpleLineSymbol,
          SimpleRenderer, SimpleMarkerSymbol, LabelClass, BasemapToggle, HomeButton, Search, LocateButton, 
        urlUtils, Directions,
          Draw, CartographicLineSymbol, Units, ElevationsProfileWidget,
          Color, arrayUtils, parser, InfoTemplate, ClassBreaksRenderer, CheckBox, domConstruct,           
          keys,SnappingManager, Measurement, GeometryService,esriConfig, has,BasemapGallery,
          LabelLayer, TextSymbol, Font, SimpleLineSymbol
      ) {

     var dojoConfig = { parseOnLoad: true };
        var legendLayers = [];          
     
     parser.parse();

     // VARIABLES FOR ELEVATION WIDGET
     var tb, epWidget, lineSymbol;
     
            
     var gp, mapClickEvt;
     
      var map = new Map("map", {
      basemap: "gray",
      center: [-79.665, 37.629],
      zoom: 8,
       logo: false,
       showLabels : true
      });

// SNIP  bunch of code for other stuff

});
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
KenBuja
MVP Esteemed Contributor

You have to declare variable "map" before line 1

var map;
 
require([
   "esri/map", "esri/geometry/webMercatorUtils", "dojo/dom", "esri/layers/FeatureLayer", "esri/dijit/Legend","esri/symbols/SimpleFillSymbol", 
‍‍‍‍

then on line 35, you would use

map = new Map("map", {
  basemap: "gray",
  center: [-79.665, 37.629],
  zoom: 8,
  logo: false,
  showLabels : true
});‍‍‍‍‍‍‍
0 Kudos
jaykapalczynski
Honored Contributor

I moved to the top in my main js file

var map; 
var gp, mapClickEvt;
     
 require([
        "esri/map", "esri/geometry/webMercatorUtils", "dojo/dom", "esri/layers/FeatureLayer", "esri/dijit/Legend","esri/symbols/SimpleFillSymbol", 
          "esri/geometry/Extent", "esri/layers/ArcGISDynamicMapServiceLayer", 'esri/layers/WMSLayer', 'esri/layers/WMSLayerInfo', "esri/layers/ImageParameters",
          "dojo/_base/array", "dojo/on", "esri/graphic","esri/graphicsUtils","esri/tasks/Geoprocessor","esri/tasks/FeatureSet","esri/tasks/LinearUnit","esri/symbols/SimpleLineSymbol",
          "esri/renderers/SimpleRenderer", "esri/symbols/SimpleMarkerSymbol","esri/layers/LabelClass", "esri/dijit/BasemapToggle","esri/dijit/HomeButton", "esri/dijit/Search", "esri/dijit/LocateButton",
        "esri/urlUtils", "esri/dijit/Directions",
          "esri/toolbars/draw","esri/symbols/CartographicLineSymbol","esri/units","esri/dijit/ElevationProfile",
          "esri/Color", "dojo/_base/array", "dojo/parser", "esri/InfoTemplate", "esri/renderers/ClassBreaksRenderer","dijit/form/CheckBox", "dojo/dom-construct",       
          "dojo/keys","esri/SnappingManager","esri/dijit/Measurement","esri/tasks/GeometryService","esri/config",     "esri/sniff","esri/dijit/BasemapGallery",     
          "esri/layers/LabelLayer", "esri/symbols/TextSymbol", "esri/symbols/Font", "esri/symbols/SimpleLineSymbol", 
        "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dijit/layout/AccordionContainer","esri/dijit/Scalebar","dijit/TitlePane", "dojo/domReady!"
      ], function(
        Map, webMercatorUtils, dom, FeatureLayer, Legend, SimpleFillSymbol, 
          Extent, ArcGISDynamicMapServiceLayer, WMSLayer, WMSLayerInfo, ImageParameters,
          array, on, Graphic, graphicsUtils, Geoprocessor, FeatureSet, LinearUnit, SimpleLineSymbol,
          SimpleRenderer, SimpleMarkerSymbol, LabelClass, BasemapToggle, HomeButton, Search, LocateButton, 
        urlUtils, Directions,
          Draw, CartographicLineSymbol, Units, ElevationsProfileWidget,
          Color, arrayUtils, parser, InfoTemplate, ClassBreaksRenderer, CheckBox, domConstruct,           
          keys,SnappingManager, Measurement, GeometryService,esriConfig, has,BasemapGallery,
          LabelLayer, TextSymbol, Font, SimpleLineSymbol
      ) {

    var dojoConfig = { parseOnLoad: true };
    var legendLayers = [];          
     
    parser.parse();


    map = new Map("map", {
      basemap: "gray",
      center: [-79.665, 37.629],
      zoom: 8,
      logo: false,
      showLabels : true
    });

I then have this in my 2nd js file

require([           
    "esri/map","dojo/domReady!"
    ], function(
        Map
    ) {

     map.on("click", function(e){
        alert("clicked");
    });

});

I know get this error

init.js:28 Uncaught TypeError: Cannot read property 'on' of undefined
at elevationprofile.js:7
at ia (init.js:28)
at init.js:28
at ja (init.js:28)
at ga (init.js:28)
at f (init.js:30)
at HTMLScriptElement.<anonymous> (init.js:35)

0 Kudos
KenBuja
MVP Esteemed Contributor

So if I comment out almost all of the requires, leaving

require([
   "esri/map", "esri/geometry/webMercatorUtils", "dojo/dom", "dojo/parser",//"esri/dijit/Legend", //"esri/symbols/SimpleFillSymbol",
    //      "esri/geometry/Extent", "esri/layers/ArcGISDynamicMapServiceLayer", 'esri/layers/WMSLayer', 'esri/layers/WMSLayerInfo', "esri/layers/ImageParameters",
    //      "dojo/_base/array", "dojo/on", "esri/graphic", "esri/graphicsUtils", "esri/tasks/Geoprocessor", "esri/tasks/FeatureSet", "esri/tasks/LinearUnit", "esri/symbols/SimpleLineSymbol",
    //      "esri/renderers/SimpleRenderer", "esri/symbols/SimpleMarkerSymbol", "esri/layers/LabelClass", "esri/dijit/BasemapToggle", "esri/dijit/HomeButton", "esri/dijit/Search", "esri/dijit/LocateButton",
    //    "esri/urlUtils", "esri/dijit/Directions",
    //      "esri/toolbars/draw", "esri/symbols/CartographicLineSymbol", "esri/units", "esri/dijit/ElevationProfile",
    //      "esri/Color", "dojo/_base/array",  "esri/InfoTemplate", "esri/renderers/ClassBreaksRenderer", "dijit/form/CheckBox", "dojo/dom-construct",
    //      "dojo/keys", "esri/SnappingManager", "esri/dijit/Measurement", "esri/tasks/GeometryService", "esri/config", "esri/sniff", "esri/dijit/BasemapGallery",
    //      "esri/layers/LabelLayer", "esri/symbols/TextSymbol", "esri/symbols/Font", "esri/symbols/SimpleLineSymbol",
    //    "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dijit/layout/AccordionContainer", "esri/dijit/Scalebar", "dijit/TitlePane", "dojo/domReady!"
 "dojo/domReady!"
], function (Map, webMercatorUtils, dom, parser
    //Map, webMercatorUtils, dom, FeatureLayer, Legend, SimpleFillSymbol,
    //  Extent, ArcGISDynamicMapServiceLayer, WMSLayer, WMSLayerInfo, ImageParameters,
    //  array, on, Graphic, graphicsUtils, Geoprocessor, FeatureSet, LinearUnit, SimpleLineSymbol,
    //  SimpleRenderer, SimpleMarkerSymbol, LabelClass, BasemapToggle, HomeButton, Search, LocateButton,
    //urlUtils, Directions,
    //  Draw, CartographicLineSymbol, Units, ElevationsProfileWidget,
    //  Color, arrayUtils, parser, InfoTemplate, ClassBreaksRenderer, CheckBox, domConstruct,
    //  keys, SnappingManager, Measurement, GeometryService, esriConfig, has, BasemapGallery,
    //  LabelLayer, TextSymbol, Font, SimpleLineSymbol
      ) {‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

then the code works. If I uncomment the next module, "esri/layers/FeatureLayer", then the code fails. The time it takes to load all those modules was causing a problem. To fix that, I used dom/ready on the other js file. This makes

require(["dojo/ready", "esri/map", "dojo/domReady!"], function (ready, Map) {
    ready(function () {
        map.on("click", function (e) {
            alert("clicked");
        });
    });
});‍‍‍‍‍‍‍‍‍‍‍‍‍‍

From the documentation

dojo/ready registers a function to run when the DOM is ready and all outstanding require() calls have been resolved, and other registered functions with a higher priority have completed.

jaykapalczynski
Honored Contributor

OK I removed dojo/domReady and replaced with dojo/ready and it works...go figure...

THANKS..

dojo/ready", "esri/map", "dojo/domReady!
0 Kudos