Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arcgis (ESRI) dojo causing multipleDefine with component using define for jQuery

I wish to include a component written by someone in my ArcGIS web application.

However when I include, I always face a multipleDefine problem at the console window.

There are 2 ways to solve it, which is by moving the following script below the component.

<script src="https://js.arcgis.com/3.14/"></script>

or by declaring defer on the script

<script defer src="https://js.arcgis.com/3.14/"></script>

However these does not solve the root of the problem because basically the component will not use AMD but rather browser global to declare it

Do you guys have any ideas? I have included a jsFiddle for this at:

https://jsfiddle.net/h9ztsrm3/5

Simply turn on your console window and you can see the multipleDefine issue, thanks!

For simplicity, I have also included another jsFiddle that does not use arcgis dojo AMD but requirejs AMD, while the resultant problem is different, any solution on that would probably solve the main topic here too

https://jsfiddle.net/w33zwjhx/


More information below:

1) I'm trying to produce a web application with arcgis map using asp.net mvc 5 with bootstrap 3

2) asp.net mvc 5 will add the following script tag by default

<script src="/Scripts/jquery-2.1.4.js"></script>
<script src="/Scripts/bootstrap.js"></script>

3) I proceed to integrate map into my application

<script src="/Scripts/esri/3.14/init.js"></script>

4) Step 3 will implicitly start dojo as arcgis is coupled with dojo

5) I found a good component I can use in the internet and proceed to integrate it

https://github.com/ehpc/bootstrap-waitingfor/blob/master/src/waitingfor.js

<script src="/Scripts/ehpc/waitingdialog/src/js/waitingdialog.js"></script>

6) However the component has the following codes and since dojo has already been loaded via arcgis, the content of the ' if ' statement is executed

if (typeof define === 'function' && define.amd) {
    define(['jquery'], function ($) {
        return (root.waitingDialog = factory($));
    });
}

7) I now got the problem as per jsFiddle

8) I research to understand more but the following website told me define(['jquery']) is the correct way to write a component

http://ifandelse.com/its-not-hard-making-your-library-support-amd-and-commonjs/

like image 243
bryan Avatar asked Oct 18 '22 21:10

bryan


2 Answers

I think I have answered my own question. The key points are:

1) using define(['jquery']) in 3rd party component is correct

2) since jquery is defined before arcgis dojo, we have to write the following after dojo has been loaded to fix it

// jquery was loaded before AMD is available, now that AMD is made available after loading dojo,
// register jquery as an AMD module so that AMD compatible plugins are able to locate jquery
define('jquery', [], function () { return jQuery; });

3) we also have to define dojoConfig before arcgis dojo

var dojoConfig = {
  packages: [{
    name: 'newmodule',
    location: '/Scripts/newmodule',
    main: 'newmodulejs'
  }]
};

4) now we can use any 3rd party component

require(['newmodule', 'dojo/domReady!'], function (newModule) {
    // newModule.myfunc();
});

These define and require got me really bad

like image 97
bryan Avatar answered Oct 23 '22 11:10

bryan


It's not clear to me what you're really trying to do here, but it seems like you're creating your own problem in the code you added in the HTML pane of that fiddle.

jQuery already defines itself as an AMD module if it is loaded in the presence of an AMD loader. If you load jQuery second, the following will work, because jQuery happens to define itself with a static module ID:

<script src="https://js.arcgis.com/3.14/"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
    require([ 'jquery' ], function ($) { ... });
</script>

(Although jQuery and $ will still also be registered globally as well.)

An even more ideal way to load jQuery directly through the AMD loader would be as follows:

<script>
    var dojoConfig = {
        async: true,
        paths: {
            jquery: 'https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min'
        }
    };
</script>
<script src="https://js.arcgis.com/3.14/"></script>
<script>
    require([ 'jquery' ], function ($) { ... });
</script>
like image 41
Ken Franqueiro Avatar answered Oct 23 '22 11:10

Ken Franqueiro