Select to view content in your preferred language

ArcGIS JavaScript programming, single responsibility, singletons and best practices?

2663
13
Jump to solution
06-18-2013 09:02 AM
YgorThomaz
Emerging Contributor
Hello guys,

I started my programming in two days, my "main.js" file starts getting gigantic and hard to understand.

Do you know any documentation that can help me with the Javascript programming with Dojo and ArcGIS API?
I believe that to minimize the problem will need to singleton for the object map. Questions:

- How do you guys organize your files (.JS)? Separate files for subsequent "compilation"?
- Do you use MVVM?
- Do you use the single responsibility principle for the scope of require([]) (Dojo)?

Thanks, any opnion is welcome!
1 Solution

Accepted Solutions
JasonScharf
Deactivated User
I work on a moderately sized application (> 50K LOC) that makes heavy use of the JavaScript API.

We use an in-house MVVM library similar to Knockout because it allows us to cleanly separate UI and business code from markup and presentation. It also allows us to avoid writing DOM handling code, instead relying on data-binding attributes to do the work for us. This cuts down on a significant amount of code, and provides a great deal of organization.

We also rely heavily on compilation, compiling many small units of code/markup/CSS into a single JavaScript file. This allows us to keep a large number of modular components separate and organized during development. We find this approach is integral to maintaining non-trivial applications. Dojo's build system has similar functionality, if you go down that route.

I really recommend you take a look at TypeScript if you're planning on writing large applications.

We have recently ported a great deal of our code to TypeScript, as it allows us to write type-safe code and offers code completion in Visual Studio and other IDEs. TypeScript supports classes, modules, namespaces, interfaces, and the upcoming 0.9 release supports Generics. It's totally compatible with JavaScript.

Check it out!

View solution in original post

0 Kudos
13 Replies
derekswingley1
Deactivated User
We recommend using Dojo's tools for creating classes and modules to manage your code when you start building large apps. Our Dojo and AMD page is the best place to start. You'll find links to writing classes and widgets from there.

Regarding MVVM, we don't typically recommend MVVM, MVC or any other flavor of MVW (model-view-whatever). You can use any MVW framework alongside our API, including Backbone, Angular, Ember...the list goes on. Here's a repo that Matt Driscoll and I put together for examples using Backbone, Angular and Knockout at the Esri Dev Summit earlier this year:  https://github.com/driskull/framework-samples-js

To your last point, about "single responsibility principle for the scope of require([])", I think the answer is yes, if I understand correctly. Typically, in things that I build, I create classes (one per AMD module) and then wire them up with a main.js or app.js file which contains a single require(). I don't typically put anything in the global namespace except when debugging. If I find myself with a huge list of dependencies for any require() or define() call, I take that as a sign that it's probably time to refactor and that I'm trying to do too much at one time.
0 Kudos
YgorThomaz
Emerging Contributor
We recommend using Dojo's tools for creating classes and modules to manage your code when you start building large apps. Our Dojo and AMD page is the best place to start. You'll find links to writing classes and widgets from there.

Regarding MVVM, we don't typically recommend MVVM, MVC or any other flavor of MVW (model-view-whatever). You can use any MVW framework alongside our API, including Backbone, Angular, Ember...the list goes on. Here's a repo that Matt Driscoll and I put together for examples using Backbone, Angular and Knockout at the Esri Dev Summit earlier this year:  https://github.com/driskull/framework-samples-js

To your last point, about "single responsibility principle for the scope of require([])", I think the answer is yes, if I understand correctly. Typically, in things that I build, I create classes (one per AMD module) and then wire them up with a main.js or app.js file which contains a single require(). I don't typically put anything in the global namespace except when debugging. If I find myself with a huge list of dependencies for any require() or define() call, I take that as a sign that it's probably time to refactor and that I'm trying to do too much at one time.


Hello Derek,

I'm reading this article: http://jpenet.blogspot.ca/2012/11/using-amd-pattern-to-create-modular.html

I will take into consideration all your advice.

Thank you!
0 Kudos
JasonScharf
Deactivated User
I work on a moderately sized application (> 50K LOC) that makes heavy use of the JavaScript API.

We use an in-house MVVM library similar to Knockout because it allows us to cleanly separate UI and business code from markup and presentation. It also allows us to avoid writing DOM handling code, instead relying on data-binding attributes to do the work for us. This cuts down on a significant amount of code, and provides a great deal of organization.

We also rely heavily on compilation, compiling many small units of code/markup/CSS into a single JavaScript file. This allows us to keep a large number of modular components separate and organized during development. We find this approach is integral to maintaining non-trivial applications. Dojo's build system has similar functionality, if you go down that route.

I really recommend you take a look at TypeScript if you're planning on writing large applications.

We have recently ported a great deal of our code to TypeScript, as it allows us to write type-safe code and offers code completion in Visual Studio and other IDEs. TypeScript supports classes, modules, namespaces, interfaces, and the upcoming 0.9 release supports Generics. It's totally compatible with JavaScript.

Check it out!
0 Kudos
YgorThomaz
Emerging Contributor
Ty Jason,

What do you use to compiling many small units of code/markup/CSS into a single JavaScript file?

TypeScript is amazing!
0 Kudos
JasonScharf
Deactivated User
We use a fairly simple custom tool that glues together our code and encodes CSS and HTML into the output .js file, based on configuration files.


Also, I just now got word that TypeScript 0.9 was released today. More info here: http://blogs.msdn.com/b/typescript/archive/2013/06/18/announcing-typescript-0-9.aspx
0 Kudos
JianHuang
Deactivated User
Dynamic typing is one of the core concepts of JavaScript, which is powerful. Which one is better is arguable. But since JavaScript has dynamic typing nature, I'm not sure if adding a typescript upon it makes a lot of sense. I haven't compared the performance of typescript. But JavaScript normally has the reputation of "SLOW", you may not want to sacrifice more just for type safe. Once you get used to dynamic typing, you will find it's a very flexible and interesting feature.
0 Kudos
ReneRubalcava
Esri Frequent Contributor
I had put this demo together a while ago, it's not exactly how I do things these days, but still gives an idea about breaking stuff up into modular pieces.
https://github.com/odoe/AGSModularDemo
For example, I don't use "views" anymore, I changed it to controllers and my widgets are actually all done in Angular.js now.

I used to use r.js to build my apps from when I was still using requirejs, but since the API moved to 3.x, I just use Grunt now.
http://gruntjs.com/

I was finally convinced to go Grunt after talking with one of the AGRC guys about how they use Dojo to do their builds. It's just a lot easier for me to automate my tests, less compiles and minification.
https://github.com/agrc/AGRCJavaScriptProjectBoilerPlate

If I find myself with a huge list of dependencies for any require() or define() call, I take that as a sign that it's probably time to refactor and that I'm trying to do too much at one time.


This is always a good sign that something could probably be broken out. I've taken to writing lots of smaller functions I can string together, which I'm fine with, but a long define/require list makes me feel bad.
0 Kudos
YgorThomaz
Emerging Contributor

...

To your last point, about "single responsibility principle for the scope of require([])", I think the answer is yes, if I understand correctly. Typically, in things that I build, I create classes (one per AMD module) and then wire them up with a main.js or app.js file which contains a single require(). I don't typically put anything in the global namespace except when debugging. If I find myself with a huge list of dependencies for any require() or define() call, I take that as a sign that it's probably time to refactor and that I'm trying to do too much at one time.


Derek,

Do you have any examples posted to this simple architecture that you described above?

I read all the recommended readings. I decided to start with a simple project, my first goal is to understand the process of initial load of my scripts and JS and how can I work with objects(singletons) that will be used in other classes or modules as the MAP object.

I am creating a prototype to convince the staff that work with javascript is a good idea at this time. But really I'm a little confused right now. I agree with Jian about "typescript" at this time.

Thank you for your attention!
0 Kudos
derekswingley1
Deactivated User
The gas prices by state sample is a simple example that follows the conventions discussed in this thread. The JS API site itself is another example if you example the source.
0 Kudos