Running Dojo on RequireJS - dojo

I am using Dojo 1.9.1 and RequireJS
I implemented it using this code:
<script src="require.js"></script>
<script type="text/javascript">
requirejs.config({
baseUrl: location.pathname.replace(/\/[^/]+$/, '') + '/js/', // magic!
packages: [
{
name: 'dojo',
location: "http://ajax.googleapis.com/ajax/libs/dojo/1.9.1/dojo/"
}
]
});
</script>
...
..
<script>
require(["dojo/domReady!"], function() {
......
});
</script>
it will throw some exceptions about has.js not work correctly
Uncaught TypeError: Object function (){} has no method 'add' has.js:8
Uncaught Error: Load timeout for modules: dojo/domReady!_unnormalized2
Does any one have an explanation, or an idea about how to solve it?

The CDN version of Dojo is built assuming that you are using the Dojo loader in order to decrease code size. Part of the code removal is the alternative has.js implementation that is used if a loader doesn’t include one (like RequireJS). You can use a regular downloaded version of Dojo with RequireJS and it will work fine, but you can’t use the CDN version.

Related

requirejs loading file from different path

I've a webpage , where I've included the requirejs via script tag like -
<script data-main="/media/course-book-app/courses.require.main.js" src="/media/common/vendor/requirejs/require.js"></script>
On Safari browser, I'm getting error like -
What is causing this issue?
This issue is very frequent on Safari but on chrome it is less frequent.
Testing URL
From https://requirejs.org/docs/errors.html#scripterror (which is linked right there in the error). Follow the instructions and look at the script that caused the error
This occurs when the script.onerror function is triggered in a
browser. This usually means there is a JavaScript syntax error or
other execution problem running the script. To fix it, examine the
script that generated the error in a script debugger.
This error may not show up in IE, just other browsers, and instead, in
IE you may see the No define call for ... error when you see "Script
error". This is due to IE's quirks in detecting script errors.
Here is the way to use requirejs correctly. This ensures the configuration gets loaded before loading any module -
define('requireconfig', function(){
require.config({
paths: {
"jquery": "/common/vendor/jquery/jquery-1.9.1.min",
"backbone": "/common/vendor/backbone/backbone.min-1.1.2",
"underscore": mediaPath + "/common/vendor/underscore/underscore.min-1.7.0"
},
shim: {
backbone : {
deps: ["jquery","underscore"],
exports: "Backbone"
},
}
});
});
define('main', ['requireconfig'], function () {
'use strict';
});
// loading main module which loads the requirejs configuration
requirejs(['main'],()=>{
requirejs(['jquery'], ($)=>{//jquery loaded});
}, ()=>{//error loading module})

ArcGIS Api (Esri) triggering multipleDefine error

I have this weird issue while using ArcGIS API for JavaScript v4.4 in my code. I am trying to build an Excel Web Add-in in which I would like to load an ArcGIS map but when I load ArcGIS I get a multipleDefine error.
ArcGIS is getting bundled with Dojo which is used as the loader for all the ArcGIS/esri packages. I have no other choices to load my own custom JS bundles with Dojo because of the way ArcGIS has built their API. So I can't decide to not use Dojo and thus not getting the multipleDefine error.
I load my own JS files like this:
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>
<script>
var dojoConfig = {
parseOnLoad: false,
async: false,
// we make aliases for our js file
aliases:  [
['index',  './Bundles/index.js'],
],
};
</script>
<script src="https://js.arcgis.com/4.4/init.js"></script>
<script>
require(['index'], function (index) {
//...do something
});
</script>
When I restart the page I get a multipleDefine error once in every two/three trials. After a lot of investigation I understood that the error lies with the Office.js API but I had a hard time to find a good solution.
After a while I found the cause of the problem; we cannot start office-js and Dojo together because they both want to add scripts in the head tag of our page and somehow they end up in conflict with one another, thus we get the dreaded multipleDefined Dojo error and some of our files do not get loaded.
Once this cause was identified I decided to solve it by making sure Dojo, Argis and my custom js files got loaded once Office and dependencies were fully loaded.
I implemented it like this in my js code:
// This Dojo config variable has to be defined before Dojo is loaded in our scripts
var dojoConfig = {
// we make aliases for our custom js file
aliases: [
['index', './Bundles/index.js'],
],
// We require our dependencies (our own code bundles) with Dojo.
// Notice that it is mandatory to bundle our js files
// as AMD Modules for Dojo to be able to load them as dependencies.
deps: ['index'],
};
// Once office has fully initialized we can add our arcgis file and let
// him load our own required javascript files.
// We cannot start Office-js and Dojo/Arcgis together because they both
// want to add scripts in the head tag of the HTML page and
// somehow they end up in conflict, thus we get the dreaded
// multipleDefined Dojo error and some of our files
// do not get loaded.
Office.initialize = function (reason) {
// we manually add the Arcgis script to the header of our page
// once we are sure Office and dependencies has fully loaded.
var tag = document.createElement('script');
tag.src = 'https://js.arcgis.com/4.4/init.js';
document.getElementsByTagName('head')[0].appendChild(tag);
};
Once this was added the code started working like a charm.

Dojo amd loading cross-domain modules at runtime

I want to load Dojo1.9 amd modules from an ad-hoc server on the www, but I won't know from where until runtime (with url params).
In essence, I want to do the equivalent of this:
require(['http://www.foo.com/SomeRandomModule'], function( SomeRandomModule ) {
// use SomeRandomModule
});
Quick and dirty way
Might have some unexpected quirks when it comes to the module system and relative paths, I haven't used it enough to say:
require([ "//host/myext/mod1/mod2.js" ],function(mod2){
// If current webpage is http:// or https:// or file://
// it tries to use the same protocol
});
Better way
Configure require() to treat all modules that start with a certain package name (e.g. foo) as coming from a particular URL. From your starter page, something like:
<script src="dojo/dojo.js"
data-dojo-config="packages:[{name:'myext',location:'//host/js/myext'}], async: 1, >
</script>
This lets you vastly improve your first example to:
require([ "myext/mod1/mod2" ],function(mod2){
});
If you are using a Dojo Bootstrap installation instead, you can avoid touching your data-dojo-config and instead put it inside the run.js startup file:
require({
baseUrl: '',
packages: [
'dojo',
'dijit',
'dojox',
'myapp',
{ name: 'myext', location: '//host/js/myext', map: {} }
]
}, [ 'myapp' ]);

on reloading/refreshing the page the dojo/ready function is not called

When refreshing/reloading a page, the dojo/ready function is not called, so the page is not loaded properly. Sometimes it is working properly; some times not.
window.onload = function() {
setTimeout(function(){document.body.style.opacity="100";},100);
require(["dojo/ready"], function(ready){
ready(function(){
alert("ready");
});
});
};
This is my window onload code. Sometimes I am getting the alert ready, sometimes not. I cannot figure out the issue.
Thanks in advance
I'd suggest to not use window.onload.
Instead, include your script as a js file like this:
<script type="text/javascript" src="/appRoot/js/my.js"></script>
Then in your my.js file:
require([ "dojo", "dojo/domReady!" ], function(dojo) {
// Code in here will be run only when the page is ready.
});
I am using this with dojo 1.7, but this is valid through 1.9.
See also the dojo/domReady! documentation.

Dojo - Issue loading widget cross-domain

I'm working on a project that requires that some custom Dojo widgets (i.e., widgets we have written ourselves) are loaded from another server. Despite my best efforts over several days, I cannot seem to get Dojo to load the widgets.
Dojo is loaded from the Google CDN, the widget is loaded from www.example.com, and the website is located at www.foo.com.
I cannot post the actual project files (this is a project for a company), but I have reproduced the error with smaller test files.
Test.html (on www.foo.com):
<html>
<div id="content"></div>
<script>
var djConfig = {
isDebug: true,
modulePaths: {
'com.example': 'http://example.com/some/path/com.example'
}
}
</script>
<script src="https://ajax.googleapis.com/ajax/libs/dojo/1.4.3/dojo/dojo.xd.js.uncompressed.js"></script>
<script type="text/javascript">
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.addOnLoad(function() {
dojo.require("com.example.widget.Test", false);
dojo.addOnLoad(function() {
new com.example.widget.Test().placeAt(dojo.byId('content'));
});
});
</script>
</html>
Test.xd.js (at www.example.com/some/path/com.example/widget/Test.xd.js):
dojo.provide("com.example.widget.Test");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.declare("com.example.widget.Test", [dijit._Widget, dijit._Templated], {
templateString: "<div dojoAttachPoint=\"div\">This is a test</div>",
postCreate: function() {
console.log("In postCreate");
console.log(this.div);
this.div.innerHTML += '!!!';
}
});
In Firebug, I am seeing an error after a delay of a few seconds saying that the cross-domain resource com.example.widget.Test cannot be loaded. However, in the 'Net' tab I am able to see that Test.xd.js is successfully downloaded, and I am able to set a breakpoint and see that the dojo.declare executes and completes without error.
I appreciate any help. Please let me know if there is any other information I can provide.
There is a different way for handling the module declarations in XD-loader. This is due to how the loader handles 'module-ready' event. You will most likely experience, that the dojo.addOnLoad never runs, since it 'knows' that certainly - some required modules are not declared.
Even so, they may very well be declared - and the change in 1.7+ versions of dojotoolkit seem to reckognize that fact. The reason for this, i believe, is that the mechanism for 'module-ready' is not implemented correctly in your myModule.xd.js modules.
It is basically a 'header' or 'closure' of the declaration, involving a few steps - wrapping everything in your basic module from dojo.provide and eof
Standard example boiler module file '{{modulePath}}/my/Tree.js'
dojo.provide("my.Tree");
dojo.require("dijit.Tree");
dojo.declare("my.Tree", dijit.Tree, {
// class definition
});
X-Domain example boiler module file '{{modulePath}}/my/Tree.xd.js
dojo._xdResourceLoaded(function(){
return {
depends: [
["provide", "my.Tree"],
["require", "dijit.Tree"]
],
defineResource: function(dojo) {
///////////////////////////////
/// Begin standard declaration
dojo.provide("my.Tree");
dojo.require("dijit.Tree");
dojo.declare("my.Tree", dijit.Tree, {
// class definition
});
/// End standard declaration
///////////////////////////////
}
}
})();