From JavaScript mess to Cleaner Code - Step 2

October 6, 2016    JavaScript Development Aurelia jQuery Clean Code

From JavaScript mess to Cleaner Code - Step 2 (jQuery with OOP)

This continues our JavaScript journey from the intro and step 1.

See the Code from the branch our in master.

jQuery can be split into classes and moved out of the html into external files. This allows bundling and minification, easier to read (classes and method names), maintain and testable code and more familiar looking code to those familiar with C# and server-side work.

The Good

  • Classes, Objects and methods
  • Easier to reason and discover dependencies and what the code’s purpose is for
  • Easier to extend and maintain
  • App.js could be broken up into more classes
  • The DOM isn’t filled with code, just html ids are necessary
  • Ability to cache data in energyDataApi.js
  • Only a few extra files

The Bad

  • Need to add scripts in order (this gets to be difficult to manage with more and more scripts)
  • Need to have server side code to switch to bundled/minified code for production, with cache-busting for version updates.
  • Still coupled to the DOM with jQuery and DOM ids. This is testable, but has its challenges
  • Dynamic DOM creation in code (I don’t like seeing <td> and HTML in JavaScript)
  • Passing around data to methods

Notice the <script> tag in the OOPWthjQuery.cshtml. It’s only 3 lines (compared to 80+) and clearly shows what app depends on.

`<script>
    $(function(){
    var appMain = new app(new energyDataApi(), new loadingIndicator());
    appMain.initialize();
    });
</script>`

The script files are added (order in the html matters) just above the <script>. <environment> is an Asp.Net Core tech.

`<environment names="Development">
    <script src="~/js/OopWithJQuery/app.js"></script>
    <script src="~/js/OopWithJQuery/energyDataApi.js"></script>
    <script src="~/js/loadingIndicator.js"></script>
</environment>`

This set of code also introduces Promises, but jQuery style, not the new ES2015 spec. I didn’t take the time to update to jQuery 3.0 , but just kept the project default. I’m also familiar with the pre 3.0 approach. There’s a big change in 3.0 to make jQuery promises closer to the spec. Promises help avoid all the callbacks and once you understand them make working wth async web service calls much easier. Here’s some code from the energyDataApi class.

`/**
  * Get the year options.
  */
energyDataApi.prototype.getYearOptions = function () {
    var _this = this;
    if(this.yearOptions.length > 0){
        // jQuery 2.2.3's way of deferreds and promises
        // browsers will have native implementation: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
        // that will vary from this approach
        return $.Deferred().result(this.yearOptions);
    }

    // return the promise
    return $.getJSON('/api/energy/yearOptions').then(function(options){
        // let's cache the results client side, it doesn't help in the current setup (we only load it once), but would help if multiple pages or other imagined scenarios
        // this shows the usefullness of a energyDataApi class, using promises, and a caching option.
        // we could also have the server return 304 and do the caching that way
        _this.yearOptions = options;
        return options;
    });
}`

Continue to Step 3: TypeScript with Knockout and RequireJs



comments powered by Disqus