The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

David_Bily (4) [Avatar] Offline
#1
Hi,

New to ArcGIS Server so the book has been very helpful. Have begun to build my own application as I read the book. In chapter 3 where you talk about breaking up code into modules, I copied and pasted the code from page 61 (I tried both named and anonymous) into a file I called sample.js which is located in js/utils. So my code looks like this:

console.log("You are here");
define('utils.sample', [
'dojo/_base/declare'
], function(declare) {
return declare({
startup: function() {
console.log('I am a defined module');
}
});
});

In my main.js file, I require sample.js and alias it with the word "Sample." I then call it as you do in your manuscript with:
var s = new Sample();
s.startup();

Seems pretty straight forward but I never see the message "I am a defined module." What am I doing wrong?
p.s. In Sample.js, I have tried defining sample.js as:
'utils/sample'
"utils/sample"
'utils.sample'
"utils.sample"
'sample'
"sample"

all to no avail. Is there a complete listing of your code that works somewhere on the internet? I don't see a file called sample.js anywhere in the chapter 3 listing that comes with the MEAP book. Thanks for any feedback.
David_Bily (4) [Avatar] Offline
#2
Re: modularity code
Asked my question on ESRI's forum and Ujjwal Narayan was kind enough to help me out. He suggested aliasing the two digits in my code. This had proved problematic in the past so I just removed them from the Require statement as they weren't needed anyway. Ujjwal then offered his take on my sample so I replaced my version of Sample.js with his version and it worked, the main difference being the use of "constructor." His versin of Sample.js is:

define([
'dojo/_base/declare'
], function(declare) {
return declare('utils.sample', [], {
constructor: function(opts) {
console.log('Startup constructor');
},

startup: function() {
console.log('I am a defined module');
}
});
});
rene.rubalcava (10) [Avatar] Offline
#3
Re: modularity code
Sorry for the late response.
It's odd that the constructor made a difference.

In the latest versions, which I don't think have made their way to the MEAP yet, I have removed the named modules, so
define('utils/sample', []. {});
Is now just
define(null, {});

The Dojo build tools, which are not discussed in the book, because using them with the Esri JS API is a complex task, will name the modules for you. Doing so as a developer is not something that should be done in practice. I was trying to show how AMD worked in this case, but it was probably a little confusing to include that in the book, so I took it out.

Also by passing null instead of an empty array, because even an empty array kicks off some extra logic in the declare module.
https://github.com/dojo/dojo/blob/master/_base/declare.js#L748
It's not a lot, but my tech editor pointed out that the Dojo recommendation is to pass null in place of an empty array.

I'm glad you got the module working though, any further questions, please feel free to ask.
David_Bily (4) [Avatar] Offline
#4
Re: modularity code
O.K., what I was ultimately trying to do was take a simple piece of code, put in it's own file and get it to work using proper protocol. So with that in mind, if I wanted the scalebar to be it's own file, I would:

Declare Scalebar globally
Require "esri/dijit/Scalebar"
Reference Scalebar

Then I would copy and paste the following three lines of code into a file I'll call Sample.js:

var Scalebar = new Scalebar({
map: map,
scalebarUnit: "dual"
});

This works as is, but I doubt this is correct protocol. Exactly what else should I do in Sample.js to make the scalebar functionality the best it can be?
rene.rubalcava (10) [Avatar] Offline
#5
Re: modularity code
What you'd want to do is create a file called something like myScalebar.js in a folder with a define() method that references the "esri/dijit/Scalebar", like define(['esri/dijit/Scalebar'], function(Scalebar) { return /*stuff*/ });.

Then in the your main require method reference it like
require(['myfolder/myScalebar'], function(myScalebar) { /*do stuff*/ });

The trick is when using custom modules with the ArcGIS JS API, you are working Dojo from a CDN (Content Delivery Network) so you'll need to do a little work in the configuration to load your own modules.
http://dojotoolkit.org/documentation/tutorials/1.9/cdn/

Hope that helps.
David_Bily (4) [Avatar] Offline
#6
Re: modularity code
O.K., finally got around to trying your suggestion. Didn't change anything in the main program. In other words, I require "utils/Sample", alias it as Sample. I still have a line like this --> s = new Sample();
but had to take out s.startup(); due to error in console.
This is what Sample.js looks like:

define(
["dojo/_base/declare", "esri/dijit/Scalebar"], function(declare, Scalebar){
return declare([],{
constructor : function(){
var myScalebar = new esri.dijit.Scalebar({
map: "map",
scalebarUnit: "dual",
scalebarStyle: "line",
attachTo: "bottom-left"
});
}
});
});

I get an error message that states: Uncaught TypeError: Cannot read property 'appendChild' of undefined. Apparently, this error is thrown on line 24 of the scalebar diji. I couldn't find much about this error on the internet. Any suggestions?