How to import third party librarys (AMD)

5720
9
Jump to solution
07-09-2012 05:31 AM
JörgPossin
New Contributor III
Hi

I use the ESRI JavaScript framework 3.0 which includes Dojo 1.7. It works well but I want to import an additionally library (this one: http://www.thejekels.com/dojo/cbtree_AMD.html). The example uses a local copy of Dojo but I want to use the Dojo package inside the ESRI API and in my web folder a copy of the third party library.

I do not know if this a ESRI API problem but I am not very familiar with JavaScript.

Regards
Jörg
0 Kudos
1 Solution

Accepted Solutions
ReneRubalcava
Frequent Contributor
Check out the migrating to 3.0 page
http://help.arcgis.com/EN/webapi/javascript/arcgis/help/jshelp/migration_30.htm

I was able to load the cbtree library as a package and got no errors when I added it to some defines. I didn't try to actually build a tree node though.

dojoConfig = {     async: 1,     parseOnLoad: true,     packages: [       {         name: "cbtree",         location: location.pathname.replace(/\/[^/]+$/, "") + "src/libs/cbtree"       }     ] };


Then I was able to load it in an app like this.
define(['cbtree/Tree', 'cbtree/models/TreeStoreModel'], function(Tree, TreeStoreModel) {  return {   treeTest: function(){    console.log("cbtree files loaded:", Tree, TreeStoreModel);   }  }; });


Chrome shows the js files were loaded.

The docs for this dijit talk about adding these files to the dojo directory and stuff, which in this simple test wasn't needed.

Hope that helps a bit.

View solution in original post

0 Kudos
9 Replies
ReneRubalcava
Frequent Contributor
Check out the migrating to 3.0 page
http://help.arcgis.com/EN/webapi/javascript/arcgis/help/jshelp/migration_30.htm

I was able to load the cbtree library as a package and got no errors when I added it to some defines. I didn't try to actually build a tree node though.

dojoConfig = {     async: 1,     parseOnLoad: true,     packages: [       {         name: "cbtree",         location: location.pathname.replace(/\/[^/]+$/, "") + "src/libs/cbtree"       }     ] };


Then I was able to load it in an app like this.
define(['cbtree/Tree', 'cbtree/models/TreeStoreModel'], function(Tree, TreeStoreModel) {  return {   treeTest: function(){    console.log("cbtree files loaded:", Tree, TreeStoreModel);   }  }; });


Chrome shows the js files were loaded.

The docs for this dijit talk about adding these files to the dojo directory and stuff, which in this simple test wasn't needed.

Hope that helps a bit.
0 Kudos
JörgPossin
New Contributor III
Hey Rene

Your example code helps me to understand how import packages works but it still does not work. I get in firebug this error:

Error: multipleDefine
 

...push(_2f1);_2f1=null;_2e9=_2eb=-1;}else{if(cc=="="){var _2f7=("|~^$*".indexOf(lc...

?v=3.0 (Zeile 15)
src: dojoLoader
?v=3.0 (Zeile 15)
info: Object { pid="cbtree", mid="cbtree/Tree", pack={...}, mehr...}


It seems that I am define the cbtree package twice or more but I don't. Here is my code:

 
        ... do some css stuff ...

        <script type="text/javascript">
            var dojoConfig = {
                parseOnLoad : true,
                isDebug : true,
                packages : [{
                    name : "cbtree",
                    location : location.pathname.replace(/\/[^/]+$/, "") + "/js/cbtree",
                }]
            };

        </script>

        <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=3.0"></script>

        <script type="text/javascript">
            dojo.require("dijit.dijit")
            dojo.require("dijit.layout.BorderContainer");
            dojo.require("dijit.layout.ContentPane");
            dojo.require("dijit.layout.AccordionContainer");
            dojo.require("esri.map");
            dojo.require("esri.dijit.Legend");
            dojo.require("esri.layers.FeatureLayer");
            dojo.require("esri.dijit.OverviewMap");
            dojo.require("esri.dijit.Scalebar");
            dojo.require("dojo.parser");
            dojo.require("dijit.TooltipDialog");
            dojo.require("dojo.number");
            dojo.require("dijit.form.CheckBox");

            var map, layer
            var mapServiceURL = "path to our server"
            var featureLayerArray = new Array()
            var activeLayer
            var mouseOverEvent, mouseOutEvent

            function init() {

                require(["dojo/data/ItemFileReadStore", "dojo/store/Observable", "cbtree/Tree", "cbtree/models/ForestStoreModel", "dojo/query", "dojo/domReady"], function(ItemFileReadStore, Observable, Tree, ForestStoreModel, dndSource, query) {
                    
                    var store = new ItemFileReadStore({
                        url : "data/layer.json"
                    });

                    var model = new ForestStoreModel({
                        store : store,
                        query : {
                            type : 'thema'
                        },
                        rootId : 'root',
                        rootLabel : 'Themen'
                    });

                    var tree = new Tree({
                        model : model,
                        id: "MenuTree",
                        branchIcons: true,
                        branchReadOnly: true,
                        checkBoxes: true,
                        nodeIcons: true
                    });
0 Kudos
JörgPossin
New Contributor III
I solved the problem but my solution does not use the "define" method from dojo. In fact I don't know the difference between "require" and "define". But this code works for me and I can work with it 🙂

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
        <!--The viewport meta tag is used to improve the presentation and behavior of the samples
        on iOS devices-->
        <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
        <title>Checkbox Tree</title>
        
         <style type="text/css">
            @import "http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/dojo/dijit/themes/claro/claro.css";
            @import "src/libs/cbtree/themes/claro/claro.css";
        </style>      

        <script type="text/javascript">
            var dojoConfig = {
               
                parseOnLoad : true,
                packages : [{
                    name : "cbtree",
                    location : location.pathname.replace(/\/[^/]+$/, "") + "/src/libs/cbtree"
                }]
            };
        </script>

        <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=3.0"></script>
        <script type="text/javascript">
             require(["dojo/_base/connect", "dojo/store/Observable", "dojo/query", "dojo/domReady", "cbtree/Tree","cbtree/models/ForestStoreModel", "dijit/layout/BorderContainer", "dijit/layout/ContentPane"], function(connect, Observable, query, domReady, Tree, ForestStoreModel) {
         
                function checkBoxClicked( item, nodeWidget, evt ) {
                    alert( "The new state for " + this.getLabel(item) + " is: " + nodeWidget.get("checked") );
                }
                var store = new dojo.data.ItemFileWriteStore({
                        url : "data/small.json"
                    });

                    var model = new ForestStoreModel({
                        store : store,
                        query : {
                            type : 'thema'
                        },
                        rootId : 'root',
                        rootLabel : 'Themen'
                    });

                    tree = new Tree({
                        model : model,
                        id: "MenuTree",
                        showRoot : false,
                        branchIcons: true,
                        branchReadOnly: true,
                        checkBoxes: true,
                        nodeIcons: true
                    });
                    connect.connect( tree, "onCheckBoxClick", model, checkBoxClicked );
                  
                    domReady( function() {
                       tree.placeAt('legendPane');
                    });
                    console.debug("fertig geladen")
                init();
            });             

        </script>
    </head>
    <body class="claro">       
                <div id="legendPane">
                    sdgfhkl
                </div>       
    </body>
</html>


I used ArcGIS JS API 3.0, Dojo 1.7 (inside the ArcGSI JS API), and a local version of cbtree (Version 0.9 from github).
0 Kudos
KevinMacLeod1
Occasional Contributor III
I am trying to do this same thing.

I want to load the ESRI API 3.3 from ESRI's server.

I want to load some Dojo modules locally. (WURadar and AGSJSTOC, both of which are discussed in various threads here).

However I can see in Firebug it keeps trying to load WURadar and AGSJS TOC modules:
NetworkError: 404 Not Found - http://serverapi.arcgisonline.com/jsapi/arcgis/3.3/js/dojo/agsjs/TOC.js
NetworkError: 404 Not Found - http://serverapi.arcgisonline.com/jsapi/arcgis/3.3/js/dojo/modules/WURadarLayer.js

However, I thought I followed the Dojo docs on Dojoconfig http://dojotoolkit.org/documentation/tutorials/1.8/dojo_config/
It discusses this exact scenario, using Dojo hosted on a CDN but loading local packages. (in the middle of that page)

My Dojoconfig is the following:

dojoConfig = {
    has: {
        "dojo-firebug": true,
        "dojo-debug-messages": true
    },
    async: true,
    waitSeconds: 3,
    tlmSiblingOfDojo: false,
    baseUrl: 'location.pathname.replace(/\/[^/]+$/, "")',

    packages: [{  
        name: "agsjs",
        location: "/js/lib/agsjs/"    
    }, {
        name: "modules",
       location: "/js/lib/WURadarLayer/"
    }],
};


I also tried using this:  location: location.pathname.replace(/\/[^/]+$/, "") + "/js/lib/WURadarLayer/"
instead of using the relative location in baseURL, and put a + "/" and ./ up in baseURL at the end, etc. and just a blank "" in baseUrl.

Also tried baseUrl  as "js" and "js/" etc. And calling dojo.js and init.js directly in inline <script> tags in index.html (it found these but still would look for Measurement.js, etc and other ESRI API and Dojo files locally. Conversely if I point it to the ESRI server in DojoConfig it finds the ESRI and Dojo files but not the local AMD modules, WURadar and AGSJS TOC. And the page doesn't load, either way, due to not finding files.

Tried many combinations, to no avail. I understand the concept in the official Dojo docs on Dojoconfig above, it seems pretty straightforward. I presume it's a simple issue related to dojoconfig syntax.

Anyone else had this issue and solved it, or know the cause of this issue?

Or can someone provide and example of a site with this configuration, with local modules but loading the ESRI API / Dojo from ESRI servers?


Here is the following in my index.html

<!DOCTYPE html>
<html>
    <head>
      <!-- ---  header stuff .... -->
    
  <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.3/js/dojo/dijit/themes/claro/claro.css">    
    <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.3/js/esri/css/esri.css">

    
    <script src="js/my/dojoConfig.js"></script>
        
        
            <script>var dojoConfig = { parseOnLoad: true };</script>
    <script src="//serverapi.arcgisonline.com/jsapi/arcgis/3.3/"></script>
   
        <script src="js/my/myMap.js"></script>
    </head>
    <body class="claro">
   
      <!--  ---- body stuff   .... -->
     



Here is the outline of the myMap.js (the main .js file)

require(["esri/map",
        "esri/layers/FeatureLayer",
        "esri/dijit/Popup",
        "esri/tasks/Query",
        "esri/dijit/Geocoder",
        "esri/dijit/Scalebar",
        "esri/dijit/Legend",
        "esri/dijit/Print",
        "agsjs/TOC",
        "modules/WURadarLayer",
        "dojo/DeferredList",
        "dojo/_base/connect",
        "esri/layers/FeatureLayer",
        "esri/dijit/Measurement",
        "dijit/TitlePane",
        "esri/dijit/OverviewMap"
], function (map) {


    
    var initialExtent = esri.geometry.geographicToWebMercator(
           new esri.geometry.Extent(-81.20953, 32.12281, -81.17640, 32.14837,
           new esri.SpatialReference({ wkid: 3857 })
           ));

    var popup = new esri.dijit.Popup(null, dojo.create("div"));


    map = new esri.Map("map", {
        slider: false,
        wrapAround180: true,         //set wraparound to false if the extent is limited.
        showAttribution: false,
        logo: false,                 // or, just hide the esri logo and don't ask me no questions :)
        infoWindow: popup,
        slider: true,
        sliderStyle: "small",
        autoResize: true,
        extent: initialExtent
    });
    var basemap = new esri.layers.ArcGISTiledMapServiceLayer(getWebData.ESRIWorldTopoMap);
    map.addLayer(basemap); 
    dojo.place(popup.domNode, map.root);  

////// lots more stuff, and widgets, including a radar loop layer (WURadar) and Table of Contents (AGSJS TOC)

 map.setExtent(initialExtent);

    map.resize();

    dojo.connect(map, "onLoad", function () {

        dojo.connect(dijit.byId("map"), "resize", map, map.resize);
    });
})
0 Kudos
JeffJacobson
Occasional Contributor III
In fact I don't know the difference between "require" and "define".


You use define to define a new module. You use require when you are only consuming other modules and not defining your own.
0 Kudos
KevinMacLeod1
Occasional Contributor III
You use define to define a new module. You use require when you are only consuming other modules and not defining your own.


Is that perhaps the issue in our code?

However it works perfect, third-party modules and all, when I run it all local. It only chokes when attempting to use the ESRI API off the server but these modules local, i.e. it tries to find them on ESRI's server.

Does anyone here have an example site with this setup? I'm looking around and will post back here if I find a nice example or solve this.
0 Kudos
KevinMacLeod1
Occasional Contributor III
update:  I followed the dojoConfig syntax from Nianwei Liu's site for Charlotte here http://forums.arcgis.com/threads/75725-BasicViewer-with-TOC  He has this same config.

Now all the GETs are resolving ok, as seen in Firebug, all "200 OK". It gets both the API and Dojo from ESRI servers as well as finding my two local modules.

But the site doesn't load. Some "multiple define" errors with Firebug console and TOC not working... But the showstopper is Measurement.js having this.distance undefined. Between this and Measurment.js not working with the API deployed locally (http://forums.arcgis.com/threads/77948-Measurement-work-with-local-API), I'm starting to suspect there is a bug in Measurement.js, and the way it interacts with other parts of the API or Dojo.

When I simply comment out the instatatiation code block, making a new Measurement.js widget... at least the page loads, but the TOC etc. are not there. Still multiple define issue. I followed Nianwei's pattern for loading local modules. Everything looks good. Anyone else seeing this? Or has anyone else successfully created a website with local modules but calling ESRI's CDN, and including a Measurement widget in their site? Aside from Nianwei! Not sure why his site works, but it has the complex ESRI template structure. However, I'm reviewing his site now, looking for enlightenment on this. I'll post back if I solve this.

My website is at GitHub:
https://github.com/kevinsagis/KSAVesriserver/
0 Kudos
KevinMacLeod1
Occasional Contributor III
I set async to false in dojoConfig and now Measurement works. That was it!

So I am thinking there are bugs with Measurement.js, in terms of being Dojo 1.8 compliant. 

Now I have to get it working with another site I made to deploy with local API. Not sure if it will be the same issue or not. Will post results back here when done.
0 Kudos
KevinMacLeod1
Occasional Contributor III
Same issue, same workaround/fix. Works local now too.

The API needs to be updated to allow Measurement.js to work when async is set to true in dojoConfig.
0 Kudos