ESRI Javascript API Custom AMD Modules - how to break up my long JS code

901
4
Jump to solution
11-29-2021 03:11 PM
B-
by
New Contributor II

Hi all, 

There are instances where the JavaScript code for my apps becomes long and difficult to navigate. I have been exploring the option of breaking the long code out into separate JavaScript modules and loading them in through "require". However is seems like i can only return one function per module. Therefore i end up calling modules from modules.

Is this the proper way to handle this? Is there a better way to break out my code into separate files which i can then call in my main.js? For example:

I need to parse json data. Instead of having all of that code for parsing  in main.js (pretend it has callbacks and more than one function), I put the json parsing code in a file called parse.js. Then from main.js I access parse.js and call its functions. like the following

parse = "./parse.js"   

and then simply call     

parse.parseJsonFunction(api_url)       

or something along those lines.

 

Here is my current workflow with the AMD modules. I made the code as simple as i could. Notice how I am referencing module2 from module1. Is this how this is supposed to be done?

Index.html

<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>
      Intro to MapView - Create a 2D map | Sample | ArcGIS API for JavaScript
      4.21
    </title>
    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }
    </style>

    <link
      rel="stylesheet"
    />
    <script src="https://js.arcgis.com/4.21/"></script>

    <script src="main.js"></script>

  </head>
  <body>
    <div id="viewDiv"></div>
  </body>
</html>
 
 
 
main.js
 
var loc = location.pathname.replace(/\/[^/]+$/, '');
require({
packages: [
    { name: "modules", location: loc + "/modules"}
]
},["esri/Map", "esri/views/MapView","modules/module1"], (Map, MapView, module1) => {
    const map = new Map({
      basemap: "topo-vector"
    });

    const view = new MapView({
      container: "viewDiv",
      map: map,
      zoom: 4,
      center: [15, 65] // longitude, latitude
    });


           
    var value_from_modules = module1.myfunction(5, 5)
    alert(value_from_modules)
  });

 

 

 

module1.js

define(
    ["./module2"],
    function(module2) {
        return {
            myfunction: function(a,b) {
                alert("entered module1")
                var add = module2.add(a,b)
                return add;
            }
         }
    }
)
 
 
 module2.js
 
define(
    [],
    function() {
        return {
            add: function(a,b) {
                alert("entered module2")
                return a + b;
            }
         }
    }
)
Tags (3)
0 Kudos
1 Solution

Accepted Solutions
shaylavi
Esri Contributor

Not sure why you'd assume there's only a single function in a module. Have you ever looked inside modules you're importing? they're all filled with functions - that's the whole purpose of a module.

As Dojo isn't the modern way of writing javascript (like in the new versions of ES6+), the way to separate code blocks seems a bit "hacky" and the "define" helps to create separate modules (as you already understood). Each module contains a "main" function, which is then used as a namespace.

What's the error you're getting if you add more functions? like the following -

 

 
define(
    [],
    function() {
        return {
            add: function(a,b) {
                alert("entered module2")
                return a + b;
            },
            delete: function(a,b) {
                alert("another function")
                return a + b;
            }
         }
    }
)

 

Shay

View solution in original post

4 Replies
shaylavi
Esri Contributor

Not sure why you'd assume there's only a single function in a module. Have you ever looked inside modules you're importing? they're all filled with functions - that's the whole purpose of a module.

As Dojo isn't the modern way of writing javascript (like in the new versions of ES6+), the way to separate code blocks seems a bit "hacky" and the "define" helps to create separate modules (as you already understood). Each module contains a "main" function, which is then used as a namespace.

What's the error you're getting if you add more functions? like the following -

 

 
define(
    [],
    function() {
        return {
            add: function(a,b) {
                alert("entered module2")
                return a + b;
            },
            delete: function(a,b) {
                alert("another function")
                return a + b;
            }
         }
    }
)

 

Shay
B-
by
New Contributor II

Hi @shaylavi thank you for the fast response. I am glad to hear that I was wrong in my assumption. I assumed that it was only one function per module because I was unable to figure out how to allow functions to interact with each other in a module. I am new to JavaScript so I am still trying to wrap my head around things. What i mean "allow functions to interact with each other in a module" is that i cannot call a function from another function in a module as in the example below. 

 

main.js

var loc = location.pathname.replace(/\/[^/]+$/, '');
require({
packages: [
    { name: "modules", location: loc + "/modules"}
]
},["esri/Map", "esri/views/MapView","modules/module1"], (Map, MapView, module1) => {
    const map = new Map({
      basemap: "topo-vector"
    });

    const view = new MapView({
      container: "viewDiv",
      map: map,
      zoom: 4,
      center: [15, 65] // longitude, latitude
    });


           
    var add_module = module1.add(5, 5)
    var subtract_module = module1.subtract(5, 5)
    var multiply_module = module1.multiply(5, 5)



    alert(add_module)
    alert(subtract_module)
    alert(multiply_module)
   
  });
 
module1.js
 
define(
    [],
    function() {
        return {
            add: function(a,b) {
                return a + b;
            },
            subtract: function(a,b) {
                multiply(a,b)
                return a - b;
            },
            multiply: function(a,b) {
                alert("entered my function")
                return a*b
            }


         }
    }
)
 
 
 
the error in the Dev Tools is 
 
 
Uncaught ReferenceError: multiply is not defined
at Object.add (modules/module1.js:9)
at main.js:21
at Db (js.arcgis.com/:21)
at js.arcgis.com/:22
at Gb (js.arcgis.com/:21)
at Ta (js.arcgis.com/:22)
at Sa (js.arcgis.com/:24)
at HTMLScriptElement.<anonymous> (js.arcgis.com/:26)
 
 
 
Is this expected behavior? 
0 Kudos
shaylavi
Esri Contributor

Hi, this is really basic javascript knowledge - I strongly suggest you find a good javascript tutorial to teach you these things, which will make your life so much easier in the long run.

To call a function within the same module you need to use "this" - this.multiply(a, b).

this points at the current scope of work, which includes all the other functions as well.

 

Shay
0 Kudos
B-
by
New Contributor II

@shaylavi  Thank you for your time. I will accept your first response as the answer so this question will be marked as 'solved'