<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Coding Smackdown TV</title>
	<atom:link href="http://codingsmackdown.tv/feed/" rel="self" type="application/rss+xml" />
	<link>http://codingsmackdown.tv</link>
	<description>Putting a headlock on the coding lifestyle!</description>
	<lastBuildDate>Wed, 22 May 2013 14:07:47 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Hailing All Frequencies &#8211; Communicating in AngularJS with the Pub/Sub Design Pattern</title>
		<link>http://codingsmackdown.tv/blog/2013/04/29/hailing-all-frequencies-communicating-in-angularjs-with-the-pubsub-design-pattern/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=hailing-all-frequencies-communicating-in-angularjs-with-the-pubsub-design-pattern</link>
		<comments>http://codingsmackdown.tv/blog/2013/04/29/hailing-all-frequencies-communicating-in-angularjs-with-the-pubsub-design-pattern/#comments</comments>
		<pubDate>Tue, 30 Apr 2013 00:03:51 +0000</pubDate>
		<dc:creator>Jim Lavin</dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[code.explode]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Controller]]></category>
		<category><![CDATA[Design Pattern]]></category>
		<category><![CDATA[Directive]]></category>
		<category><![CDATA[Pub/Sub]]></category>
		<category><![CDATA[Publish/Subscribe]]></category>
		<category><![CDATA[Publishers]]></category>
		<category><![CDATA[Service]]></category>
		<category><![CDATA[Subscribers]]></category>

		<guid isPermaLink="false">http://codingsmackdown.tv/?p=246</guid>
		<description><![CDATA[Hailing All Frequencies! Is anybody out there? This is the USS AngularJS, we have a problem our services are speaking in Klingon and our controllers can&#8217;t communicate with their Ferengi directives. Can anyone help us! I don&#8217;t know how many times I&#8217;ve seen a question about what is the best way to communicate between components [...]]]></description>
				<content:encoded><![CDATA[<p>Hailing All Frequencies! Is anybody out there? This is the USS AngularJS, we have a problem our services are speaking in Klingon and our controllers can&#8217;t communicate with their Ferengi directives. Can anyone help us!</p>
<p>I don&#8217;t know how many times I&#8217;ve seen a question about what is the best way to communicate between components in AngularJS. A lot of the time the resulting answer is to use the $rootScope object to $broadcast a message to anyone who might be listening for it. But, that really isn&#8217;t the best way to do it. Broadcasting messages between components means that they need to know too much about how things are coded reducing their modularity and re-use.</p>
<p>In this article I show you how to use the Pub/Sub Design Pattern for inter-component communications in AngularJS.</p>
<p><span id="more-246"></span></p>
<p>AngularJS has several ways that you can use to communicate between components, but the most used methods require your components to know too much about those they are communicating with, which increases the coupling between components and decreases their modularity and cohesion. This makes it hard to reuse your components in other applications.</p>
<p>By using the Publish/Subscribe design pattern we can decrease the coupling between components and encapsulate the details used for component communications. This will help increase your component&#8217;s modularity, testability and reuse.</p>
<p>The implementation of the Publish/Subscribe pattern I&#8217;ll be covering was devised by Eric Burley, @eburley, in his post <a href="http://eburley.github.io/2013/01/31/angularjs-watch-pub-sub-best-practices.html">angularjs.org watch, on pub sub, and you.</a>. </p>
<p>The example application, I&#8217;ll be describing, shows how you can use the Publish/Subscribe pattern for inter-controller communications and controller to service communications. You can find the source code out on GitHub under my repository <a href="https://github.com/lavinjj/angularjs-pubsub">angularjs-pubsub</a>.</p>
<h2>First We Need a Channel to Communicate Through</h2>
<p>First let&#8217;s talk about the service that is used by the publishers and subscribers to communicate with each other. I&#8217;ve defined a service that will provide an interface that has a publish and subscribe method for each message we want to send. </p>
<p>In the code below I have defined two internal messages; _EDIT_DATA_, used to indicate that we need to edit the item passed in the message and _DATA_UPDATED_, used to indicate that our data has changed. Since these are defined internally to our service none of the consumers of the service will have access to them, helping to keep the implementation details hidden.  </p>
<p>Each message in turn, has two methods; one to publish the message to the subscribers and another one that the subscribers will user to register a callback method that will be called when the message is received.</p>
<p>The methods to publish the messages to the subscribers are editData, on line 9, and dataUpated, on line 19. They use the $rootScope.$broadcast method to publish the private notification message to the event handlers.</p>
<p>The event registration methods, use the $scope.$on methods to set up a watch that will get called whenever the message is broadcast and in turn call the event handler that was passed when the subscriber registered with the service. Since the subscriber also passes in its own scope, we can use it to perform the watch on the message and avoid the heavy code needed to manage a list of listeners. The registration methods are onEditData, on line 13 and onDataUpdated on line 23.</p>
<p>To hide the implementation details, I&#8217;ve used a Revealing Module Pattern to only return back the methods that I want to be accessible by the consumers.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
angular.module(['application.services'])
    // define the request notification channel for the pub/sub service
    .factory('requestNotificationChannel', ['$rootScope', function ($rootScope) {
        // private notification messages
        var _EDIT_DATA_ = '_EDIT_DATA_';
        var _DATA_UPDATED_ = '_DATA_UPDATED_';

        // publish edit data notification
        var editData = function (item) {
            $rootScope.$broadcast(_EDIT_DATA_, {item: item});
        };
        //subscribe to edit data notification
        var onEditData = function($scope, handler) {
            $scope.$on(_EDIT_DATA_, function(event, args) {
               handler(args.item);
            });
        };
        // publish data changed notification
        var dataUpdated = function () {
            $rootScope.$broadcast(_DATA_UPDATED_);
        };
        // subscribe to data changed notification
        var onDataUpdated = function ($scope, handler) {
            $scope.$on(_DATA_UPDATED_, function (event) {
                handler();
            });
        };
        // return the publicly accessible methods
        return {
            editData: editData,
            onEditData: onEditData,
            dataUpdated: dataUpdated,
            onDataUpdated: onDataUpdated
        };
    }])
</pre>
<h2>Publishing a Message</h2>
<p>To publish a message is pretty simple, first we need to include a dependency to the requestNotificationChannel in our controller, service or directive. You can see this in line 2 in the dataService definition below. When an event occurs in the component that needs to signal others that a change has occurred, you just need to call the appropriate notification method on the requestNotificationChannel. If you look at the saveHop, deleteHop and addHop methods of the dataService, you&#8217;ll see they all call the dataUpdated method on the requestNotificationChannel which will then signal the listeners who have registered with the onDataUpdated method.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
    // define the data service that manages the data
    .factory('dataService', ['requestNotificationChannel', function (requestNotificationChannel) {
        // private data
        var hops = [
            { "_id": { "$oid": "50ae677361d118e3646d7d6c"}, "Name": "Admiral", "Origin": "United Kingdom", "Alpha": 14.75, "Amount": 0.0, "Use": "Boil", "Time": 0.0, "Notes": "Bittering hops derived from Wye Challenger.  Good high-alpha bittering hops. Use for: Ales Aroma: Primarily for bittering Substitutions: Target, Northdown, Challenger", "Type": "Bittering", "Form": "Pellet", "Beta": 5.6, "HSI": 15.0, "Humulene": 0.0, "Caryophyllene": 0.0, "Cohumulone": 0.0, "Myrcene": 0.0, "Substitutes": ""} ,
            { "_id": { "$oid": "50ae677361d118e3646d7d6d"}, "Name": "Ahtanum", "Origin": "U.S.", "Alpha": 6.0, "Amount": 0.0, "Use": "Boil", "Time": 0.0, "Notes": "Distinctive aromatic hops with moderate bittering power from Washington. Use for: Distinctive aroma Substitutes: N/A", "Type": "Aroma", "Form": "Pellet", "Beta": 5.25, "HSI": 30.0, "Humulene": 0.0, "Caryophyllene": 0.0, "Cohumulone": 0.0, "Myrcene": 0.0, "Substitutes": ""} ,
            { "_id": { "$oid": "50ae677361d118e3646d7d6e"}, "Name": "Amarillo Gold", "Origin": "U.S.", "Alpha": 8.5, "Amount": 0.0, "Use": "Boil", "Time": 0.0, "Notes": "Unknown origin, but character similar to Cascade. Use for: IPAs, Ales Aroma: Citrus, Flowery Substitutions: Cascade, Centennial", "Type": "Aroma", "Form": "Pellet", "Beta": 6.0, "HSI": 25.0, "Humulene": 0.0, "Caryophyllene": 0.0, "Cohumulone": 0.0, "Myrcene": 0.0, "Substitutes": ""} ,
            { "_id": { "$oid": "50ae677361d118e3646d7d6f"}, "Name": "Aquila", "Origin": "U.S.", "Alpha": 6.5, "Amount": 0.0, "Use": "Boil", "Time": 0.0, "Notes": "Aroma hops developed in 1988.  Limited use due to high cohumolone.Used for: Aroma hops Substitutes: ClusterNo longer commercially grown.", "Type": "Aroma", "Form": "Pellet", "Beta": 3.0, "HSI": 35.0, "Humulene": 0.0, "Caryophyllene": 0.0, "Cohumulone": 0.0, "Myrcene": 0.0, "Substitutes": ""} ,
            { "_id": { "$oid": "50ae677361d118e3646d7d70"}, "Name": "Auscha (Saaz)", "Origin": "Czech Republic", "Alpha": 3.3, "Amount": 0.0, "Use": "Boil", "Time": 0.0, "Notes": " Use for: Pilsners and Bohemian style lagers Aroma: Delicate, mild, clean, somewhat floral -- Noble hops Substitute: Tettnanger, LublinExamples: Pulsner Urquell", "Type": "Aroma", "Form": "Pellet", "Beta": 3.5, "HSI": 42.0, "Humulene": 0.0, "Caryophyllene": 0.0, "Cohumulone": 0.0, "Myrcene": 0.0, "Substitutes": ""} ,
        ];
        // sends notification that data has been updated
        var saveHop = function(hop) {
            requestNotificationChannel.dataUpdated();
        };
        // removes the item from the array and sends a notification that data has been updated
        var deleteHop = function(hop) {
            for(var i = 0; i < hops.length; i++) {
                if(hops[i]._id.$oid === hop._id.$oid) {
                    hops.splice(i, 1);
                    requestNotificationChannel.dataUpdated();
                    return;
                }
            };
        };
        // internal function to generate a random number guid generation
        var S4 = function() {
            return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
        };
        // generates a guid for adding items to array
        var guid = function () {
          return (S4() + S4() + "-" + S4() + "-4" + S4().substr(0,3) + "-" + S4() + "-" + S4() + S4() + S4()).toLowerCase();
        };
        // function to add a hop to the array and sends a notification that data has been updated
        var addHop = function(hop) {
            hops.id.$oid = guid();
            hops.push(hop);
            requestNotificationChannel.dataUpdated();
        };
        // returns the array of hops
        var getHops = function() {
            return hops;
        };
        // returns a specific hop with the given id
        var getHop = function(id) {
            for(var i = 0; i < hops.length; i++) {
                if(hops[i]._id.$oid === id) {
                    return hops[i];
                }
            };
        };
        // return the publicly accessible methods
        return {
            getHops: getHops,
            getHop: getHop,
            saveHop: saveHop,
            deleteHop: deleteHop,
            addHop: addHop
        }
    }]);
</pre>
<h2>Receiving Notification Events</h2>
<p>Receiving event notifications from the requestNotificationChannel is just as simple, except we need to pass in a callBack handler that will do something with the notification once the message is sent. Again we will need to add a dependency to the requestNotificationChannel to our controller, service or directive, you can see this on line 2 of the code for the view1-controller below. Next we need to define an event callback handler that will respond to the event notification, you can see this on line 5 below. Next we need to register our callback handler with the requestNotificationChannel by calling onDataUpdated and passing in the scope from our controller and the callback handler, we do this on line 9 below.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
    //define the controller for view1
    .controller('view1-controller', ['$scope', 'dataService', 'requestNotificationChannel', function($scope, dataService, requestNotificationChannel) {
        $scope.hops = dataService.getHops();

        var onDataUpdatedHandler = function() {
            $scope.hops = dataService.getHops();
        }

        requestNotificationChannel.onDataUpdated($scope, onDataUpdatedHandler);

        $scope.onEdit = function(hop) {
            requestNotificationChannel.editData(hop);
        }

        $scope.onDelete = function(hop) {
            dataService.deleteHop(hop);
        }
    }]);
</pre>
<h2>Controller to Controller Communication</h2>
<p>We can use the requestNotificationChannel to communicate between controllers as well. We just need to have one controller act as a publisher and one as a subscriber. If you look at the onEdit method of the view1-controller on line 11 above, it sends an editData message with the item that needs to be edited using the requestNotificationChannel. The view2-controller below registers its onEditDataHandler with the requestNotificationChannel on lines 5 thru 9 below. So whenever the view1-controller sends the editData message with the item to edit, the view2-controller gets notified of the editData request and takes the item received and assigns it to its model.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
    //define the controller for view1
    .controller('view2-controller', ['$scope', 'dataService', 'requestNotificationChannel', function($scope, dataService, requestNotificationChannel) {
        $scope.hop = null;

        var onEditDataHandler = function(item) {
            $scope.hop = item;
        };

        requestNotificationChannel.onEditData($scope, onEditDataHandler);

        $scope.onSave = function() {
            dataService.saveHop($scope.hop);
            $scope.hop = null;
        }

        $scope.onCancel = function() {
            $scope.hop = null;
        }
    }]);
</pre>
<h2>Always Have Well Documented Interfaces</h2>
<p>One of the things that may not be apparent, is that we are using an interface to communicate between components, and with any interface, they need to be well documented in order to be properly used. In the example above, without the right documentation, consumers of the onEditData message would never know that an item is passed to the call back handler. So as you start to use the pattern, its good practice to document the methods so those consuming your notification services know what to expect.</p>
<h2>The Wrap Up</h2>
<p>So I've covered how to use the Publish/Subscribe pattern for component communications in your AngularJS App. The pattern allows you to decouple your components from internal messages and promotes better reuse. You can take using the Publish/Subscribe pattern even farther by replacing all communication between your components. This pattern works especially well when you have a lot of asynchronous requests in your services and want to cache the data in your service to reduce communications with the server side.</p>
<p>I hope you find this helpful, as always you can find the code out on my GitHub site under my repository <a href="https://github.com/lavinjj/angularjs-pubsub">angularjs-pubsub</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://codingsmackdown.tv/blog/2013/04/29/hailing-all-frequencies-communicating-in-angularjs-with-the-pubsub-design-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Localizing Your AngularJS Apps: Yet Another Update</title>
		<link>http://codingsmackdown.tv/blog/2013/04/24/localizing-your-angularjs-apps-yet-another-update/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=localizing-your-angularjs-apps-yet-another-update</link>
		<comments>http://codingsmackdown.tv/blog/2013/04/24/localizing-your-angularjs-apps-yet-another-update/#comments</comments>
		<pubDate>Wed, 24 Apr 2013 19:26:52 +0000</pubDate>
		<dc:creator>Jim Lavin</dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[code.explode]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[AngualrJS]]></category>
		<category><![CDATA[Apps]]></category>
		<category><![CDATA[Attribute]]></category>
		<category><![CDATA[Devs]]></category>
		<category><![CDATA[Directive]]></category>
		<category><![CDATA[Element]]></category>
		<category><![CDATA[Filter]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[Localization]]></category>
		<category><![CDATA[Placeholders]]></category>
		<category><![CDATA[Service]]></category>
		<category><![CDATA[Token]]></category>
		<category><![CDATA[Translations]]></category>

		<guid isPermaLink="false">http://codingsmackdown.tv/?p=236</guid>
		<description><![CDATA[So you are probably really jazzed about the addition of the new directive to the angularjs-localizationservice project and the fixes to help improve it’s performance. But, now that you are probably using the project I bet you are probably saying the same thing my devs and designers were saying, “Hey Jim, this new directive really [...]]]></description>
				<content:encoded><![CDATA[<p>So you are probably really jazzed about the addition of the new directive to the <a href="https://github.com/lavinjj/angularjs-localizationservice">angularjs-localizationservice</a> project and the fixes to help improve it’s performance. But, now that you are probably using the project I bet you are probably saying the same thing my devs and designers were saying, “Hey Jim, this new directive really works great, but how do we do translations for placeholders and titles?”</p>
<p>Well, this post is going to cover a new directive that’s been added to the project just to handle such things.</p>
<p><span id="more-236"></span></p>
<h2>The i18n Attribute Directive</h2>
<p>In the beginning there was the localize service which provided you with localized resource strings, but did nothing for binding them into your HTML. Next came along the i18n filter which did a good job of binding the localized string into your HTML, but proved to be a performance pig and couldn’t handle dynamic values in a localize string. Then came along the i18n directive which helped to improve performance and handle dynamic values in localized strings.</p>
<p>But, then came the need to have all text within the page localized, even that text which was hidden away from the end user, and so, along came the i18n Attribute directive, which handle just such a problem.</p>
<h2>The Code</h2>
<p>The i18n Attribute directive is pretty much the same as the i18n directive except it expects an additional parameter to be appended to the localization resource string token which indicates which attribute to set the value when the localized string is returned.</p>
<p>If you want to pass dynamic values for the string, those should come after the attribute parameter. Then the directive will walk through and replace the numbered place holders with their values.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">    .directive('i18nAttr', ['localize', function (localize) {
        var i18NAttrDirective = {
            restrict: "EAC",
            updateText:function(elm, token){
                var values = token.split('|');
                // construct the tag to insert into the element
                var tag = localize.getLocalizedString(values[0]);
                // update the element only if data was returned
                if ((tag !== null) &amp;&amp; (tag !== undefined) &amp;&amp; (tag !== '')) {
                    if (values.length &gt; 2) {
                        for (var index = 2; index &lt; values.length; index++) {
                            var target = '{' + (index - 2) + '}';
                            tag = tag.replace(target, values[index]);
                        }
                    }
                    // insert the text into the element
                    elm.attr(values[1], tag);
                }
            },
            link: function (scope, elm, attrs) {
                scope.$on('localizeResourcesUpdated', function() {
                    i18NAttrDirective.updateText(elm, attrs.i18nAttr);
                });

                attrs.$observe('i18nAttr', function (value) {
                    i18NAttrDirective.updateText(elm, value);
                });
            }
        };

        return i18NAttrDirective;
    }]);
</pre>
<h2>How to Use It</h2>
<p>Using the i18n Attribute directive is pretty much the same as using the i18n directive. The only difference is that the name of the attribute you want to populate.</p>
<p>So if we have a local resource file that looks like below:</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">[
    {
        "key":"_Greeting_",
        "value":"Site localization example using the resource localization service",
        "description":"Home page greeting text"
    },
    {
        "key":"_HomeTitle_",
        "value":"Resource Localization Service",
        "description":"Home page title text"
    },
    {
        "key":"_HomeControllerTitle_",
        "value":"List Example",
        "description":"Home Pane Title"
    },
    {
        "key":"_HomeControllerBlob_",
        "value":"Now is the time for all good men to come to the aide of their country.",
        "description":"text example"
    },
    {
        "key":"_FormControllerTitle_",
        "value":"Form example",
        "description":"Add/Edit Person Form Title"
    },
    {
        "key":"_FirstNameLabel_",
        "value":"First Name",
        "description":"Label for first name field"
    },
    {
        "key":"_LastNameLabel_",
        "value":"Last Name",
        "description":"Label for last name field"
    },
    {
        "key":"_EMailLabel_",
        "value":"Email",
        "description":"Label for email field"
    },
    {
        "key":"_BioLabel_",
        "value":"Bio (tell us something about you) ",
        "description":"Label for biography field"
    },
    {
        "key":"_SaveButtonLabel_",
        "value":"Save",
        "description":"Label for Save button"
    },
    {
        "key":"_CancelButtonLabel_",
        "value":"Cancel",
        "description":"Label for Cancel button"
    },
    {
        "key":"_NameHeader_",
        "value":"Name",
        "description":"Person List Name Header"
    },
    {
        "key":"_EmailHeader_",
        "value":"Email",
        "description":"Person List Name Header"
    },
    {
        "key":"_BioHeader_",
        "value":"Biography",
        "description":"Person List Bio Header"
    }
]
</pre>
<p>We can set the placeholders of a registration form like so:</p>
<pre class="dontquote prettyprint lang-html linenumstrigger linenums">&lt;div class="container-fluid" &gt;
    &lt;div class="row-fluid"&gt;
        &lt;h2 data-i18n="_FormControllerTitle_"&gt;&lt;/h2&gt;
    &lt;/div&gt;
    &lt;div class="row-fluid"&gt;
        &lt;form name="myForm" class="form-horizontal span5 well"&gt;
            &lt;div class="row-fluid"&gt;
                &lt;input type="text" ng-model="person.FirstName" required id="FirstName" name="FirstName" class="input-large" data-i18n-attr="_FirstNameLabel_|placeholder" /&gt;
            &lt;/div&gt;
            &lt;div class="row-fluid"&gt;&nbsp;&nbsp; &lt;/div&gt;
            &lt;div class="row-fluid"&gt;
                &lt;input type="text" ng-model="person.LastName" required id="LastName" name="LastName" class="input-large" data-i18n-attr="_LastNameLabel_|placeholder"/&gt;
            &lt;/div&gt;
            &lt;div class="row-fluid"&gt;&nbsp;&nbsp; &lt;/div&gt;
            &lt;div class="row-fluid"&gt;
                &lt;input type="text" ng-model="person.Email" required id="Email" name="Email" class="input-large" data-i18n-attr="_EMailLabel_|placeholder"/&gt;
            &lt;/div&gt;
            &lt;div class="row-fluid"&gt;&nbsp;&nbsp; &lt;/div&gt;
            &lt;div class="row-fluid"&gt;
                &lt;textarea ng-model="person.Bio" required id="Bio" name="Bio" class="input-xxlarge" data-i18n-attr="_BioLabel_|placeholder"&gt;&lt;/textarea&gt;
            &lt;/div&gt;
            &lt;div class="row-fluid"&gt;&nbsp;&nbsp; &lt;/div&gt;
            &lt;div class="row-fluid"&gt;
                &lt;button class="btn-primary" ng-click="savePerson()" data-i18n="_SaveButtonLabel_"&gt;&lt;/button&gt;
                &lt;button class="btn-primary" ng-click="cancel()" data-i18n="_CancelButtonLabel_"&gt;&lt;/button&gt;
            &lt;/div&gt;
        &lt;/form&gt;
    &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>You can do the same with any other attribute where you need the text to change with the language. </p>
<p>Updating values dynamically is as easy as setting up your resource string with the numbered placeholders, such as; <strong>“This is a multi replace test response {0} {1}”</strong> and add the parameters to the end of the localization token like so, <strong>TEST_ITEM2|title|ABC|123</strong>, which will result in the title attribute to be set to <strong>title=”This is a multi replace test response ABC 123”</strong>.</p>
<h2>The Wrap Up</h2>
<p>Hopefully, the changes I’ve made to the library will provide you what you need to address the heavy lifting of making your app support multiple languages and you find it useful.</p>
<p>As part of the latest update I’ve also added unit tests for the service, filter and both directives to give you an idea how things work and as always you have the sample app to play with as well.</p>
<p>If you find an issue or come up with an enhancement you’d like to see included in the library, file an issue or send me a pull request and I’ll work on getting it resolved or added into the library.</p>
<p>Good Luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://codingsmackdown.tv/blog/2013/04/24/localizing-your-angularjs-apps-yet-another-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Localizing Your AngularJS Apps: Update</title>
		<link>http://codingsmackdown.tv/blog/2013/04/23/localizing-your-angularjs-apps-update/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=localizing-your-angularjs-apps-update</link>
		<comments>http://codingsmackdown.tv/blog/2013/04/23/localizing-your-angularjs-apps-update/#comments</comments>
		<pubDate>Tue, 23 Apr 2013 20:20:53 +0000</pubDate>
		<dc:creator>Jim Lavin</dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[code.explode]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Directive]]></category>
		<category><![CDATA[Filter]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[Resource Localization]]></category>
		<category><![CDATA[Service]]></category>

		<guid isPermaLink="false">http://codingsmackdown.tv/?p=220</guid>
		<description><![CDATA[In my previous article on Localization,&#160;Localizing Your AngularJS App, I provided a simple service and filter that allows you to provide language translations based on a translation file. Initially this worked for about 50% of our transalation needs, however once we started looking at the overall performance of our AngualrJS App it was apparent that [...]]]></description>
				<content:encoded><![CDATA[<p>In my previous article on Localization,&nbsp;<a title="Localizing Your AngularJS App" href="http://codingsmackdown.tv/blog/2012/12/14/localizing-your-angularjs-app/">Localizing Your AngularJS App</a>, I provided a simple service and filter that allows you to provide language translations based on a translation file. Initially this worked for about 50% of our transalation needs, however once we started looking at the overall performance of our AngualrJS App it was apparent that I needed to tweak things a bit.</p>
<p><span id="more-220"></span></p>
<p>This article covers the additional changes that has been made to my <a title="angularjs-localizationservice" href="https://github.com/lavinjj/angularjs-localizationservice">angularjs-localizationservice</a> project out on GitHub.</p>
<p>The new service, has the following new features:</p>
<ul>
<li>A new directive to help improve performance and handle dynamic localized resource strings</li>
<li>Updated the localize service to allow changing of the language on the fly</li>
<li>Fixed an issue with getLocalizedResourceString to be more efficient and simpler</li>
</ul>
<h2>Filters Degrade Performance</h2>
<p>One of the first things we found out when we had a large page to provide translations for, is that the more filters you use on a page the slower your page becomes and performance will degrade significantly. This is mainly due to the fact that the filters are being re-evaluated with every watch cycle. So, I created a directive that provided the translation functionality.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
.directive('i18n', ['localize', function(localize){
        var i18nDirective = {
            restrict:"EAC",
            updateText:function(elm, token){
                var values = token.split('|');
                if (values.length <= 1) {
                    // construct the tag to insert into the element
                    var tag = localize.getLocalizedString(values[0]);
                    // update the element only if data was returned
                    if ((tag !== null) &#038;&#038; (tag !== undefined) &amp;&amp; (tag !== '')) {
                        if (values.length &gt; 1) {
                            for (var index = 1; index &lt; values.length; index++) {
                                var target = '{' + (index - 1) + '}';
                                tag = tag.replace(target, values[index]);
                            }
                        }
                        // insert the text into the element
                        elm.text(tag);
                    };
                }
            },

            link:function (scope, elm, attrs) {
                scope.$on('localizeResourcesUpdates', function() {
                    i18nDirective.updateText(elm, attrs.i18n);
                });

                attrs.$observe('i18n', function (value) {
                    i18nDirective.updateText(elm, attrs.i18n);
                });
            }
        };

        return i18nDirective;
    }]);
</pre>
<p>So let&#8217;s discuss what&#8217;s going on in this new directive.</p>
<p>First off, we have set a dependency on the localize service so we can look up the translated strings. I have also restricted the directive to Elements, Attributes and Classes, this should pretty much cover everything you need in an HTML app.</p>
<p>Second, I added the updateText function which is responsible for looking up the localized text and update the attached element&#8217;s text. This function first splits the passed in token on &#8216;|&#8217; boundaries in order to handle dynamic strings formatted as &#8220;First Name: {0}, Last Name: {1}&#8221;. If there are additional values passed in token such as &#8220;_WELCOME_STRING_|Jim|Lavin&#8221; the resulting string would end up as &#8220;First Name: Jim, Last Name: Lavin&#8221; based on the previous example.</p>
<p>If a valid string is returned from the localize service, the updateText function will parse the returned string for dynamic values and then update the elment&#8217;s text value. If the localize service does not have a matching resource string, it will not update the element.text value.</p>
<p>Finally, The link function sets up two observers. The first observer will call the updateText function whenever the localize Service broadcasts the &#8216;localizeResourcesUpdates&#8217; message. This allows you to change languages on the fly without having to refresh the web page. We will discuss changing languages on the fly later in this article. The second observer will call the updateText function whenever the i18n attribute changes. This allows you to dynamically change the translated text by binding the value to your controller&#8217;s model.</p>
<p>You can now use the directive as shown below:</p>
<pre class="dontquote prettyprint lang-html linenumstrigger linenums">
&lt;div class="container-fluid"&gt;
    &lt;div class="row-fluid"&gt;
        &lt;h2 data-i18n="_HomeControllerTitle_"&gt;&lt;/h2&gt;
    &lt;/div&gt;
    &lt;div class="row-fluid"&gt;
        &lt;div class="well"&gt;
            &lt;div class="span1" data-i18n="_NameHeader_"&gt;&lt;/div&gt;
            &lt;div class="span2" data-i18n="_EmailHeader_"&gt;&lt;/div&gt;
            &lt;div class="span3" data-i18n="_BioHeader_"&gt;&lt;/div&gt;
            &lt;div class="span1"&gt;&lt;a href="#/new"&gt;&lt;span class="icon icon-plus"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
        &lt;/div&gt;
        &lt;div class="row-fluid" ng-repeat="person in People"&gt;
            &lt;div class="span1" ng-bind="person.FirstName + ' ' + person.LastName"&gt;&lt;/div&gt;
            &lt;div class="span2" ng-bind="person.Email"&gt;&lt;/div&gt;
            &lt;div class="span3" ng-bind="person.Bio"&gt;&lt;/div&gt;
            &lt;div class="span1"&gt;&lt;a href="#/edit/{{$index}}"&gt;&lt;span class="icon icon-edit"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>Notice the data-i18n attributes that contain the tokens for the resource strings. The nice thing about moving to the directive is that since I am using observers to watch the translation token values, the directive will only be called during the link phase, when the language changes or when the attribute value changes, keeping execution down to a minimum.</p>
<h2>Updates to the Localize Service</h2>
<p>Based on feedback from the GitHub community and tweaks to handle an initial load issue, I&#8217;ve made some updates to the localize service and will highlight them below.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
    .factory('localize', ['$http', '$rootScope', '$window', '$filter', function ($http, $rootScope, $window, $filter) {
        var localize = {
            // use the $window service to get the language of the user's browser
            language:$window.navigator.userLanguage || $window.navigator.language,
            // array to hold the localized resource string entries
            dictionary:[],
            // flag to indicate if the service hs loaded the resource file
            resourceFileLoaded:false,

            successCallback:function (data) {
                // store the returned array in the dictionary
                localize.dictionary = data;
                // set the flag that the resource are loaded
                localize.resourceFileLoaded = true;
                // broadcast that the file has been loaded
                $rootScope.$broadcast('localizeResourcesUpdates');
            },

            setLanguage: function(value) {
                localize.language = value;
                localize.initLocalizedResources();
            },

            initLocalizedResources:function () {
                // build the url to retrieve the localized resource file
                var url = '/i18n/resources-locale_' + localize.language + '.js';
                // request the resource file
                $http({ method:"GET", url:url, cache:false }).success(localize.successCallback).error(function () {
                    // the request failed set the url to the default resource file
                    var url = '/i18n/resources-locale_default.js';
                    // request the default resource file
                    $http({ method:"GET", url:url, cache:false }).success(localize.successCallback);
                });
            },

            getLocalizedString: function(value) {
                // default the result to an empty string
                var result = '';

                // make sure the dictionary has valid data
                if ((localize.dictionary !== []) &#038;&#038; (localize.dictionary.length > 0)) {
                    // use the filter service to only return those entries which match the value
                    // and only take the first result
                    var entry = $filter('filter')(localize.dictionary, function(element) {
                            return element.key === value;
                        }
                    )[0];

                    // set the result
                    result = entry.value;
                }
                // return the value to the call
                return result;
            }
        };

        // return the local instance when called
        return localize;
    } ]);
</pre>
<p>First, I added a setLanguage function that allows you to set the culture of the app on demand. It will change the internal language variable and call initLocalizedResources to load the correct language resource file from the server.</p>
<p>Second, based on an issue filed by Stein Desmet, I have changed the getLocalizedString function to pass a function to the $filter method which determines if the localized resource&#8217;s key matches the value passed in. This is needed since by default the AngularJS $filter function uses substring matching which required a lot of extra code to find the matching value if an array of matches were returned. The new method returns a single match and there is no need for the extra code, simplifying the overall solution.</p>
<h2>The Wrap Up</h2>
<p>The changes to the localization service and components makes it a great resource when you need to have an AngularJS app that supports multiple languages. Hopefully you&#8217;ll find it as useful as I have in my projects.</p>
<p>Good Luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://codingsmackdown.tv/blog/2013/04/23/localizing-your-angularjs-apps-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Response Interceptors to Show and Hide a Loading Widget: Redux</title>
		<link>http://codingsmackdown.tv/blog/2013/04/20/using-response-interceptors-to-show-and-hide-a-loading-widget-redux/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-response-interceptors-to-show-and-hide-a-loading-widget-redux</link>
		<comments>http://codingsmackdown.tv/blog/2013/04/20/using-response-interceptors-to-show-and-hide-a-loading-widget-redux/#comments</comments>
		<pubDate>Sun, 21 Apr 2013 04:13:12 +0000</pubDate>
		<dc:creator>Jim Lavin</dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[code.explode]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Broadcast]]></category>
		<category><![CDATA[Config]]></category>
		<category><![CDATA[Dependency Problem]]></category>
		<category><![CDATA[Dom]]></category>
		<category><![CDATA[Interceptor]]></category>
		<category><![CDATA[Interceptors]]></category>
		<category><![CDATA[Notification Mechanism]]></category>
		<category><![CDATA[Notifications]]></category>
		<category><![CDATA[Publishers]]></category>
		<category><![CDATA[Scope]]></category>
		<category><![CDATA[Subscribers]]></category>
		<category><![CDATA[Success]]></category>
		<category><![CDATA[Tenets]]></category>
		<category><![CDATA[Widget]]></category>

		<guid isPermaLink="false">http://codingsmackdown.tv/?p=197</guid>
		<description><![CDATA[In my previous post Using Response Interceptors to Show and Hide a Loading Widget I showed how to display a loading widget whenever an Ajax request started and hide it when all the requests completed by using a $http resource interceptor. Unfortunately, I violated one of the core tenets of AngularJS&#8217; best practices by modifying [...]]]></description>
				<content:encoded><![CDATA[<p>
In my previous post <a href="http://codingsmackdown.tv/blog/2013/01/02/using-response-interceptors-to-show-and-hide-a-loading-widget/" >Using Response Interceptors to Show and Hide a Loading Widget</a> I showed how to display a loading widget whenever an Ajax request started and hide it when all the requests completed by using a $http resource interceptor.
</p>
<p>
Unfortunately, I violated one of the core tenets of AngularJS&#8217; best practices by modifying the DOM outside of a directive. I want to thank everyone who brought that to my attention and provided examples on how to clean up the code.
</p>
<p>
This post will walk through the revised code to show how to do it properly. I will also provide a second solution, that I think is even better structured, that uses a Publish/Subscribe pattern to encapsulate the whole messaging solution and keep the publishers and subscribers from having to know anything about the notification mechanism.
</p>
<p><span id="more-197"></span></p>
<h2>Using $rootScope to Send Notifications</h2>
<p>
The first solution I&#8217;m going to cover, uses the $rootScope $broadcast method to broadcast to all children in the scope tree. This way, any controllers or directives further down the scope that are interested in the messages can set up scope $on methods for the event message and can react to it.
</p>
<p>Below is the revised code from the Sample01 solution:</p>
<p>&nbsp;</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
'use strict';

// Declare app level module which depends on filters, and services
var app = angular.module('myApp', ['mongolabResourceHttp', 'data.services']);

app.constant('_START_REQUEST_', '_START_REQUEST_');
app.constant('_END_REQUEST_', '_END_REQUEST_');

app.config(['$httpProvider', '_START_REQUEST_', '_END_REQUEST_', function ($httpProvider, _START_REQUEST_, _END_REQUEST_) {
    var $http,
        interceptor = ['$q', '$injector', function ($q, $injector) {
            var rootScope;

            function success(response) {
                // get $http via $injector because of circular dependency problem
                $http = $http || $injector.get('$http');
                // don't send notification until all requests are complete
                if ($http.pendingRequests.length < 1) {
                    // get $rootScope via $injector because of circular dependency problem
                    rootScope = rootScope || $injector.get('$rootScope');
                    // send a notification requests are complete
                    rootScope.$broadcast(_END_REQUEST_);
                }
                return response;
            }

            function error(response) {
                // get $http via $injector because of circular dependency problem
                $http = $http || $injector.get('$http');
                // don't send notification until all requests are complete
                if ($http.pendingRequests.length < 1) {
                    // get $rootScope via $injector because of circular dependency problem
                    rootScope = rootScope || $injector.get('$rootScope');
                    // send a notification requests are complete
                    rootScope.$broadcast(_END_REQUEST_);
                }
                return $q.reject(response);
            }

            return function (promise) {
                // get $rootScope via $injector because of circular dependency problem
                rootScope = rootScope || $injector.get('$rootScope');
                // send notification a request has started
                rootScope.$broadcast(_START_REQUEST_);
                return promise.then(success, error);
            }
        }];

    $httpProvider.responseInterceptors.push(interceptor);
}]);

app.directive('loadingWidget', ['_START_REQUEST_', '_END_REQUEST_', function (_START_REQUEST_, _END_REQUEST_) {
    return {
        restrict: "A",
        link: function (scope, element) {
            // hide the element initially
            element.hide();

            scope.$on(_START_REQUEST_, function () {
                // got the request start notification, show the element
                element.show();
            });

            scope.$on(_END_REQUEST_, function () {
                // got the request end notification, hide the element
                element.hide();
            });
        }
    };
}]);

app.filter('startFrom', function () {
    return function (input, start) {
        start = +start; //parse to int
        return input.slice(start);
    }
});

app.controller('myController', ['$scope', 'YeastResource', function ($scope, YeastResource) {
    $scope.yeasts = [];
    $scope.currentPage = 0;
    $scope.pageSize = 10;

    $scope.numberOfPages = function () {
        return Math.ceil($scope.yeasts.length / $scope.pageSize);
    };

    $scope.init = function () {
        YeastResource.query({}, {sort: {Type: 1, Name: 1}}).then(function (yeast) {
            $scope.yeasts = yeast;
        });
    };

    $scope.init();
}]);
</pre>
<p>&nbsp;</p>
<p>
The first change is that I&#8217;ve added two constants on lines 6 and 7, these will be used as the event messages sent by the http resource interceptor.
</p>
<p>
On line 9, I add the two constants as dependencies to the config function so they can be used by the interceptor.
</p>
<p>
On line 12, I define a variable to hold a reference to the $rootScope, which will be used to broadcast the notification messages. You might wonder why we didn&#8217;t put the $rootScope as a parameter to the config function, this is because at the time the config function is called the $rootScope doesn&#8217;t exist. Later when we need the $rootScope we get it by making a call to $injector.get(). You can see this on lines 20, 33 and 40.
</p>
<p>
Next we define the success and error handlers. Both methods work similar, we use $injector.get() to get a reference to the $http service and check to see if all the requests have completed and if so we use the reference to the $rootScope to broadcast the _END_REQUEST_ notification. You can see this on lines 18 thru 23 and on lines 31 thru 36.
</p>
<p>
Finally, we use the reference to the $rootScope to broadcast the _START_REQUEST_ in the final method of the resource interceptor on lines 41 thru 44.
</p>
<h2>The Loading Widget Directive</h2>
<p>
Instead of having to put logic into a controller to show or hide the loading widget each time a notification is received, I&#8217;ve created a directive that handles showing and hiding any element that it is applied to. Let&#8217;s discuss the code below:
</p>
<p>&nbsp;</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums:52">
app.directive('loadingWidget', ['_START_REQUEST_', '_END_REQUEST_', function (_START_REQUEST_, _END_REQUEST_) {
    return {
        restrict: "A",
        link: function (scope, element) {
            // hide the element initially
            element.hide();

            scope.$on(_START_REQUEST_, function () {
                // got the request start notification, show the element
                element.show();
            });

            scope.$on(_END_REQUEST_, function () {
                // got the request end notification, hide the element
                element.hide();
            });
        }
    };
}]);
</pre>
<p>
I again add dependencies for the _START_REQUEST_ and _END_REQUEST_ constants to the directive, this way the directive can add message handlers for each notification message. The _START_REQUEST_ handler is defined on lines 59 thru 62 and the _END_REQUEST_ handler is defined on lines 64 thru 67. Each handler shows or hides the attached element based on notification message. By default the directive hides the attached element until it receives the _START_REQUEST_ notification message.
</p>
<h2>HTML Changes</h2>
<p>The only change made to the original index.html file occurs on the div element that contains the loading widget at lines 25 thru 31, where we added the new directive to the div element at line 25.</p>
<p>&nbsp;</p>
<pre class="dontquote prettyprint lang-html linenumstrigger linenums:25">
    &lt;div id="loadingWidget" class="row-fluid ui-corner-all" style="padding: 0 .7em;" loading-widget &gt;
        &lt;div class="loadingContent"&gt;
            &lt;p&gt;
                &lt;img alt="Loading  Content" src="images/ajax-loader.gif" /&gt;&nbsp;Loading
            &lt;/p&gt;
        &lt;/div&gt;
    &lt;/div&gt;
</pre>
<p>&nbsp;</p>
<p>
Now that is pretty much all you need to do get the loading widget to display and hide whenever an $http request begins or ends.
</p>
<h2>Applying the Publish/Subscribe Pattern to the Loading Widget</h2>
<p>
Our solution works great, but there are some issues with the solution as it now sits.
</p>
<p>
Both the $http resource interceptor and the directive have to have knowledge of the notification message in order to communicate with  each other. This means that the modularity of the solution is too tightly coupled to be reused in other scenarios where we might need it.
</p>
<p>
If we wanted to display the widget whenever we had a lengthy computation execute, we would have to couple the computation service to the same two notification messages in order to make it work. But what if we wanted to move the computation engine to another application that used different notification messages? We&#8217;d have to change the dependencies we inject into the service or make some code changes to wire up the service with the new notification code.
</p>
<p>
That&#8217;s not a good thing. What we really want are code components with high cohesion and high modularity, and with minimal coupling between them. To achieve this we need to use a different mechanism that can abstract out the specifics around the notification messages and provide a standard interface that can be implemented for any type of notifications that we might want to implement.
</p>
<p>
We can use the Publish/Subscribe Pattern to encapsulate the notification details and instead provide a standard interface that any component can use to show the widget as needed.
</p>
<p>
The implementation of the Publish/Subscribe pattern I built my service on was created for AngularJS by Eric Burley, @eburley, his original post can be found at <a href="http://eburley.github.io/2013/01/31/angularjs-watch-pub-sub-best-practices.html">angularjs.org watch, on pub sub, and you.</a>, I just wrapped the implementation into a service that could be injected into the publishers and subscribers.
</p>
<p> So let&#8217;s take a look at the new code from Sample02 solution:</p>
<p>&nbsp;</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
'use strict';

// Declare app level module which depends on filters, and services
var app = angular.module('myApp', ['mongolabResourceHttp', 'data.services']);

app.config(['$httpProvider', function ($httpProvider) {
    var $http,
        interceptor = ['$q', '$injector', function ($q, $injector) {
            var notificationChannel;

            function success(response) {
                // get $http via $injector because of circular dependency problem
                $http = $http || $injector.get('$http');
                // don't send notification until all requests are complete
                if ($http.pendingRequests.length < 1) {
                    // get requestNotificationChannel via $injector because of circular dependency problem
                    notificationChannel = notificationChannel || $injector.get('requestNotificationChannel');
                    // send a notification requests are complete
                    notificationChannel.requestEnded();
                }
                return response;
            }

            function error(response) {
                // get $http via $injector because of circular dependency problem
                $http = $http || $injector.get('$http');
                // don't send notification until all requests are complete
                if ($http.pendingRequests.length < 1) {
                    // get requestNotificationChannel via $injector because of circular dependency problem
                    notificationChannel = notificationChannel || $injector.get('requestNotificationChannel');
                    // send a notification requests are complete
                    notificationChannel.requestEnded();
                }
                return $q.reject(response);
            }

            return function (promise) {
                // get requestNotificationChannel via $injector because of circular dependency problem
                notificationChannel = notificationChannel || $injector.get('requestNotificationChannel');
                // send a notification requests are complete
                notificationChannel.requestStarted();
                return promise.then(success, error);
            }
        }];

    $httpProvider.responseInterceptors.push(interceptor);
}]);

app.factory('requestNotificationChannel', ['$rootScope', function($rootScope){
    // private notification messages
    var _START_REQUEST_ = '_START_REQUEST_';
    var _END_REQUEST_ = '_END_REQUEST_';

    // publish start request notification
    var requestStarted = function() {
        $rootScope.$broadcast(_START_REQUEST_);
    };
    // publish end request notification
    var requestEnded = function() {
        $rootScope.$broadcast(_END_REQUEST_);
    };
    // subscribe to start request notification
    var onRequestStarted = function($scope, handler){
        $scope.$on(_START_REQUEST_, function(event){
            handler();
        });
    };
    // subscribe to end request notification
    var onRequestEnded = function($scope, handler){
        $scope.$on(_END_REQUEST_, function(event){
            handler();
        });
    };

    return {
        requestStarted:  requestStarted,
        requestEnded: requestEnded,
        onRequestStarted: onRequestStarted,
        onRequestEnded: onRequestEnded
    };
}]);

app.directive('loadingWidget', ['requestNotificationChannel', function (requestNotificationChannel) {
    return {
        restrict: "A",
        link: function (scope, element) {
            // hide the element initially
            element.hide();

            var startRequestHandler = function() {
                // got the request start notification, show the element
                element.show();
            };

            var endRequestHandler = function() {
                // got the request start notification, show the element
                element.hide();
            };

            requestNotificationChannel.onRequestStarted(scope, startRequestHandler);

            requestNotificationChannel.onRequestEnded(scope, endRequestHandler);
        }
    };
}]);

app.filter('startFrom', function () {
    return function (input, start) {
        start = +start; //parse to int
        return input.slice(start);
    }
});

app.controller('myController', ['$scope', 'YeastResource', function ($scope, YeastResource) {
    $scope.yeasts = [];
    $scope.currentPage = 0;
    $scope.pageSize = 10;

    $scope.numberOfPages = function () {
        return Math.ceil($scope.yeasts.length / $scope.pageSize);
    };

    $scope.init = function () {
        YeastResource.query({}, {sort: {Type: 1, Name: 1}}).then(function (yeast) {
            $scope.yeasts = yeast;
        });
    };

    $scope.init();
}]);
</pre>
<p>&nbsp;</p>
<p>
First off, We&#8217;ve removed the constant declarations and the dependencies on them across the code.
</p>
<h2>$http Resource Interceptor Changes</h2>
<p>
Starting on line 9, I&#8217;ve changed the variable that referenced the $rootScope instance to now hold a new reference to the Publish/Subscribe implementation called notificationChannel. Then I changed the  Success, Error, and $http Resource Interceptor functions to request an instance of the new notification service on lines 17, 30, and 39.
</p>
<p>
The Success and Error methods now call the requestEnded() method on the new notification service instead of broadcasting a notification message, (lines 19 and 32). The $http Resource Interceptor function now calls the requestStarted() method instead of broadcasting the notification message on line 41.
</p>
<h2>The Publish/Subscribe Service</h2>
<p>
Starting on line 49, I define the a new service that will implement the Publish/Subscribe Pattern. To hide the details of the implementation I&#8217;m using a revealing module pattern to return back an object with only four public methods; requestStarted, requestEnded, onRequestStarted and onRequestEnded. The rest of the details and the broadcasting of messages are all hidden from the consumers of the service.
</p>
<p>
We now define the notification start and end messages on lines 51 and 52. The requestStarted and requestEnded methods broadcast the notification messages and the onRequestStarted and onRequestEnded methods setup the broadcast watchers on the scope that is passed into them. The onRequestStarted and onRequestEnded methods also require that a handler function be passed into the method  so we can call it whenever the notification message is received.
</p>
<p>
At first glance it might look that the new service should have an array of listeners, but since each listener passes in it&#8217;s own scope, the service can use it to perform the watch for the notification message and the anonymous function passed to the watch calls the listener&#8217;s request handler eliminating the need for an array to hold all of the request handlers.
</p>
<h2>loadingWidget Directive Changes</h2>
<p>
The directive now has a dependency on the new Publish/Subscribe Service, requestNotificationChannel. And instead of implementing watches for the notification messages, the directive now has defined two new request handlers; startRequestHandler and endRequestHandler, which now handle showing and hiding the element the directive is attached two. Finally, the directive registers the request handlers with the Publish/Subscribe Service by passing in the directives scope and the appropriate request handler.
</p>
<h2>The Wrap Up</h2>
<p>
As I said at the beginning of this post, my original post covered how to use $http request interceptor to display and hide a loading widget. However, there were flaws in the original code. In this article I provided an updated example of the solution that follows the Best Practices of AngularJS. I then provided a second, better solution which uses the Publish/Subscribe Pattern to encapsulate the details of the messaging and improve the overall modularity of the solution.
</p>
<p>
I&#8217;ve revised the code and split both examples into two different examples; Sample01 and Sample02. I&#8217;ve also provided a stand alone module that can be used in your applications. You can find all of the source code on my <a href="https://github.com/lavinjj/angularjs-spinner">GitHub site.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://codingsmackdown.tv/blog/2013/04/20/using-response-interceptors-to-show-and-hide-a-loading-widget-redux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AngularJS Modules for Great Justice</title>
		<link>http://codingsmackdown.tv/blog/2013/04/19/angularjs-modules-for-great-justice/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=angularjs-modules-for-great-justice</link>
		<comments>http://codingsmackdown.tv/blog/2013/04/19/angularjs-modules-for-great-justice/#comments</comments>
		<pubDate>Fri, 19 Apr 2013 06:06:08 +0000</pubDate>
		<dc:creator>Jim Lavin</dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Advantages And Disadvantages]]></category>
		<category><![CDATA[Applications]]></category>
		<category><![CDATA[Apps]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Cohesion]]></category>
		<category><![CDATA[Coupling]]></category>
		<category><![CDATA[Developers]]></category>
		<category><![CDATA[Feature Package]]></category>
		<category><![CDATA[Functional Areas]]></category>
		<category><![CDATA[Java Development]]></category>
		<category><![CDATA[Layer Approach]]></category>
		<category><![CDATA[Source Code]]></category>
		<category><![CDATA[Source Package]]></category>

		<guid isPermaLink="false">http://codingsmackdown.tv/?p=172</guid>
		<description><![CDATA[First off I want to thank Joel Hooks of the DFW Area AngularJS Meetup Group for suggesting this topic and providing the title. &#8220;Modules provide an excellent mechanism for cleanly dividing up our code into functional areas. Angular allows us to use modules in many ways. Let&#8217;s take a look at modules and some of [...]]]></description>
				<content:encoded><![CDATA[<p>First off I want to thank Joel Hooks of the DFW Area AngularJS Meetup Group for suggesting this topic and providing the title.</p>
<p>&#8220;Modules provide an excellent mechanism for cleanly dividing up our code into functional areas. Angular allows us to use modules in many ways. Let&#8217;s take a look at modules and some of the approaches we can leverage to produce cleaner more manageable code.&#8221; &#8211; Joel Hooks</p>
<p>So with that, let&#8217;s get started.<br />
<span id="more-172"></span><br />
AngularJS modules are the core means by how you define the components in your app. Besides defining your components, modules provide a way to indicate the dependencies your components require and they help you organize your components to help you write modular code that can be re-used across applications.</p>
<p>As long as I have been developing with AngularJS there has always been the great best practices debate over how to structure your application. Do you use a package by feature or package by layer approach?</p>
<p>Both have their advantages and disadvantages so let&#8217;s take a quick look at each before we get into how to implement each using AngularJS.</p>
<h2>Package by Feature</h2>
<p>Package by Feature became popular in the Java development camp a few years back. The main tenet is that by keeping all the source code related to a specific feature in a single package, it was easier to develop and promote modularity across your source code. Entire features could be lifted from applications and re-used in others by just taking the source package, there was no need to bring in other packages since all the code for the feature was in one place.</p>
<p>Package-by-feature uses packages to reflect the feature set. It places all items related to a single feature (and only that feature) into a single directory. This results in packages with high cohesion and high modularity, and with minimal coupling between packages. Items that work closely together are placed next to each other. They aren&#8217;t spread out all over the application.</p>
<p>A lot of developers feel that by using Package by Feature, development on large projects is also easier since all the code you need to deal with is in one place and as the project grows following the pattern keeps everything well organized.</p>
<p>A good example of Package by Feature, is the angular-sprout seed project. All of the JavaScript files for a particular feature are included in the same directory. So, if we have three different views in our application; User, Movie, and Rating, we&#8217;ll have three directories in our source code. Each folder would include the source for the controllers, services, models and templates for the specific feature.</p>
<h2>Package by Layer</h2>
<p>If you come from a object-oriented development background, you probably are more familiar with the Package by Layer approach. The basic tenets of object-oriented design is to design by layers; data access, business logic, business entities, and user interface. This way your code is organized in layers that communicate with each other via specific interfaces. Depending on how rigid your design and coding rules are, layers only interacted with adjacent layers and never called across boundaries.</p>
<p>In package-by-layer, the highest level packages reflect the various application &#8220;layers&#8221;, instead of features. Each feature has its implementation spread out over multiple directories, over what might be loosely called &#8220;implementation categories&#8221;. Each directory contains items that usually aren&#8217;t closely related to each other. This results in packages with low cohesion and low modularity, with high coupling between packages.</p>
<p>Package by Layer works great when it comes to code that implements cross cutting concerns, however when you are developing features that span multiple layers development becomes harder since you have to deal with source files in various places. Package by Layer also promotes cross package dependencies which some feel are a bad thing.</p>
<p>A good example of Package by Layer, is the angular-seed project. All of the JavaScript files for a particular type of AngularJS component are included in the same directory or file. So, our application would be divided across the following source folders; controllers, directives, services, models, filter, etc.</p>
<h2>So What&#8217;s All This Got to do with AngularJS Code</h2>
<p>So, you&#8217;re probably wondering, &#8220;Why should I care, I write web apps?&#8221;  Actually how you partition your code has a lot to do with how you organize your project source code and how much easier it is to maintain as your project grows.</p>
<p>Depending on the size of your project your are going to have to decide on how you want your code structured. Do you keep everything in a single JavaScript file, do you break your files based on layers, do you break your files based on features, or do you structure your code directories by features and structure your source files by layers?</p>
<h2>Tiny Projects</h2>
<p>For me, if I have a very small or tiny project that does one thing, I might keep all of my source code in a single file using single module. Below is a picture of the project&#8217;s directory structure. Notice we have a single file, app.js which holds our source code and our index.html file which loads and bootstraps our app.</p>
<p><img title="Tiny Project Structure" src="http://codingsmackdown.tv/wp-content/uploads/2013/04/Tiny_Project_Structure.png" /></p>
<p>Below is the app.js file, I&#8217;ve defined a single module called myApp and used the controller and directive definition methods to define my controller and directive used by my app. Everything is in one place and easy to maintain, which is all you need when writing a very simple application.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
        angular.module('myApp', [])

        // register the controller for the app
        .controller('myController',['$scope', function($scope){
            $scope.format = 'M/d/yy h:mm:ss a';
        }])

        // Register the 'myCurrentTime' directive factory method.
        // We inject $timeout and dateFilter service since the factory method is DI.
        .directive('myCurrentTime', function($timeout, dateFilter) {
            // return the directive link function. (compile function not needed)
            return function(scope, element, attrs) {
                var format,  // date format
                    timeoutId; // timeoutId, so that we can cancel the time updates

                // used to update the UI
                function updateTime() {
                    element.text(dateFilter(new Date(), format));
                }

                // watch the expression, and update the UI on change.
                scope.$watch(attrs.myCurrentTime, function(value) {
                    format = value;
                    updateTime();
                });

                // schedule update in one second
                function updateLater() {
                    // save the timeoutId for canceling
                    timeoutId = $timeout(function() {
                        updateTime(); // update DOM
                        updateLater(); // schedule another update
                    }, 1000);
                }

                // listen on DOM destroy (removal) event, and cancel the next UI update
                // to prevent updating time after the DOM element was removed.
                element.bind('$destroy', function() {
                    $timeout.cancel(timeoutId);
                });

                updateLater(); // kick off the UI update process.
            }
        });
</pre>
<p>Below is the index.html file that instantiates the app and displays an input field that allows you to modify the time format that is used by the myCurrentTime directive to display the current date and time to the user.</p>
<pre class="dontquote prettyprint lang-html linenumstrigger linenums">
        &lt;!DOCTYPE html&gt;
        &lt;html ng-app="myApp"&gt;
        &lt;head&gt;
            &lt;title&gt;&lt;/title&gt;
            &lt;script src="lib/angular/angular.js" type="text/javascript"&gt;&lt;/script&gt;
            &lt;script src="app/app.js" type="text/javascript"&gt;&lt;/script&gt;
        &lt;/head&gt;
        &lt;body&gt;
        &lt;div ng-controller="myController"&gt;
            &lt;input type="text" ng-model="format"/&gt;
            &lt;div&gt;Time format is: {{format}}&lt;/div&gt;
            &lt;div&gt;Current time is: &lt;span my-current-time="format"&gt;&lt;/span&gt;&lt;/div&gt;
        &lt;/div&gt;
        &lt;/body&gt;
        &lt;/html&gt;
</pre>
<h2>Small Projects</h2>
<p>As your project starts to get a little more complicated you might want to start organizing your code into multiple modules, but still keep it in a single file. Below is a picture of the project&#8217;s directory structure. Notice we still have a single file, app.js which holds our source code and our index.html file which loads and bootstraps our app.</p>
<p><img title="Small Project Structure" src="http://codingsmackdown.tv/wp-content/uploads/2013/04/Small_Project_Structure.png" /></p>
<p>Below is the app.js file, I&#8217;ve defined multiple modules one for the controllers, a second for the directives and a third for the app. I have again used the controller and directive definition methods to define my controller and directive used by my app, but now they are defined on specific modules defined for each type of AngularJS component type. I have also added dependencies to the application&#8217;s module definition so everything get injected properly. Everything is in one place and easy to maintain, but is ready for when you need to separate your code into multiple files when they get too big to maintain.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
        angular.module('myControllers', [])
            // register the controller for the app
            .controller('myController',['$scope', function($scope){
                $scope.format = 'M/d/yy h:mm:ss a';
            }]);

        angular.module('myDirectives', [])
            // Register the 'myCurrentTime' directive factory method.
            // We inject $timeout and dateFilter service since the factory method is DI.
            .directive('myCurrentTime', function($timeout, dateFilter) {
                // return the directive link function. (compile function not needed)
                return function(scope, element, attrs) {
                    var format,  // date format
                        timeoutId; // timeoutId, so that we can cancel the time updates

                    // used to update the UI
                    function updateTime() {
                        element.text(dateFilter(new Date(), format));
                    }

                    // watch the expression, and update the UI on change.
                    scope.$watch(attrs.myCurrentTime, function(value) {
                        format = value;
                        updateTime();
                    });

                    // schedule update in one second
                    function updateLater() {
                        // save the timeoutId for canceling
                        timeoutId = $timeout(function() {
                            updateTime(); // update DOM
                            updateLater(); // schedule another update
                        }, 1000);
                    }

                    // listen on DOM destroy (removal) event, and cancel the next UI update
                    // to prevent updating time after the DOM element was removed.
                    element.bind('$destroy', function() {
                        $timeout.cancel(timeoutId);
                    });

                    updateLater(); // kick off the UI update process.
                }
            });

        angular.module('myApp', ['myControllers', 'myDirectives']);
</pre>
<p>Notice that the index.html file used in our example below hasn&#8217;t changed.</p>
<pre class="dontquote prettyprint lang-html linenumstrigger linenums">
        &lt;!DOCTYPE html&gt;
        &lt;html ng-app="myApp"&gt;
        &lt;head&gt;
            &lt;title&gt;&lt;/title&gt;
            &lt;script src="lib/angular/angular.js" type="text/javascript"&gt;&lt;/script&gt;
            &lt;script src="app/app.js" type="text/javascript"&gt;&lt;/script&gt;
        &lt;/head&gt;
        &lt;body&gt;
        &lt;div ng-controller="myController"&gt;
            &lt;input type="text" ng-model="format"/&gt;
            &lt;div&gt;Time format is: {{format}}&lt;/div&gt;
            &lt;div&gt;Current time is: &lt;span my-current-time="format"&gt;&lt;/span&gt;&lt;/div&gt;
        &lt;/div&gt;
        &lt;/body&gt;
        &lt;/html&gt;
</pre>
<h2>Medium Projects</h2>
<p>As your projects get larger and more complex, you might want to follow the angular-seed approach and split your source code across layers. In the sample code, I&#8217;ve broken the code out across multiple source files by layer, there is one file for the app, one for the controllers and one for the directives. Depending on how you want to structure your code, you can use a single module or multiple modules. In this example I use a single module that is assigned to a variable that is referenced by the other source files.</p>
<p>Our source code structure has changed. Now, instead of just an app directory there is now a controllers and directives directory.</p>
<p><img title="Medium Project Structure" src="http://codingsmackdown.tv/wp-content/uploads/2013/04/Medium_Project_Structure.png" /></p>
<p>Below is the contents of the app.js file. All we are doing is declaring the module that will be used by app:</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
        var myModule = angular.module('myApp', []);
</pre>
<p>Again, I am using a single module across my entire app so I am assigning it to variable, which I will reference in the other source files to define my controller and directive.</p>
<p>Below is the contents of the controllers.js file. Here we are using the myModule variable to define the controller.</p>
<pre class="dontquote prettyprint linenumstrigger linenums lang-js">
        // register the controller for the app
        myModule.controller('myController',['$scope', function($scope){
            $scope.format = 'M/d/yy h:mm:ss a';
        }]);
</pre>
<p>Below is the contents of the directives.js file. Again we are using the myModule variable to define the directive.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
        myModule.directive('myCurrentTime', function($timeout, dateFilter) {
            // return the directive link function. (compile function not needed)
            return function(scope, element, attrs) {
                var format,  // date format
                    timeoutId; // timeoutId, so that we can cancel the time updates

                // used to update the UI
                function updateTime() {
                    element.text(dateFilter(new Date(), format));
                }

                // watch the expression, and update the UI on change.
                scope.$watch(attrs.myCurrentTime, function(value) {
                    format = value;
                    updateTime();
                });

                // schedule update in one second
                function updateLater() {
                    // save the timeoutId for canceling
                    timeoutId = $timeout(function() {
                        updateTime(); // update DOM
                        updateLater(); // schedule another update
                    }, 1000);
                }

                // listen on DOM destroy (removal) event, and cancel the next UI update
                // to prevent updating time after the DOM element was removed.
                element.bind('$destroy', function() {
                    $timeout.cancel(timeoutId);
                });

                updateLater(); // kick off the UI update process.
            }
        });
</pre>
<p>Finally below is the index.html file used to load and instantiate the app. Notice how we now need to include the new source files in order to load all of our code.</p>
<pre class="dontquote prettyprint lang-html linenumstrigger linenums">
        &lt;!DOCTYPE html&gt;
        &lt;html ng-app="myApp"&gt;
        &lt;head&gt;
            &lt;title&gt;&lt;/title&gt;
            &lt;script src="lib/angular/angular.js" type="text/javascript"&gt;&lt;/script&gt;
            &lt;script src="app/app.js" type="text/javascript"&gt;&lt;/script&gt;
            &lt;script src="controllers/controllers.js" type="text/javascript"&gt;&lt;/script&gt;
            &lt;script src="directives/directives.js" type="text/javascript"&gt;&lt;/script&gt;
        &lt;/head&gt;
        &lt;body&gt;
        &lt;div ng-controller="myController"&gt;
            &lt;input type="text" ng-model="format"/&gt;
            &lt;div&gt;Time format is: {{format}}&lt;/div&gt;
            &lt;div&gt;Current time is: &lt;span my-current-time="format"&gt;&lt;/span&gt;&lt;/div&gt;
        &lt;/div&gt;
        &lt;/body&gt;
        &lt;/html&gt;
</pre>
<h2>Large to Very Large Projects</h2>
<p>As your application starts to grow and include more and more features, it is best to re-structure your source code&#8217;s directory structure by using the Package by Feature pattern and then use the Package by Layer pattern for your source files that relate to the feature. Below is a picture of the Large project&#8217;s structure. Now, we have created the folder structure based on the features in the app and the source files are based on the different AngularJS layers.</p>
<p><img title="Large Project Structure" src="http://codingsmackdown.tv/wp-content/uploads/2013/04/Large_Project_Structure.png" /></p>
<p>Below is the contents of the app.js file. We are again defining a module for our app. Notice that we have included the names of the other modules which define our features.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
        angular.module('myApp', ['my-view-controller', 'time']);
</pre>
<p>Below is contents of the my-view-controller.js app, which defines our controller for the feature.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
        // register the controller for the app
        angular.module('my-view-controller', []).controller('myController',['$scope', function($scope){
            $scope.format = 'M/d/yy h:mm:ss a';
        }]);
</pre>
<p>Since we are using the Package by Feature pattern to structure our code, we have now created a template that will be used to instantiate our controller. The reason for breaking out the HTML for the feature is because we want to have a fully re-usable package that we can pick up and drop into another application without having to drag other parts of the source application into your new app.</p>
<p>Below is the contents of my-view-partial.html:</p>
<pre class="dontquote prettyprint lang-html linenumstrigger linenums">
        &lt;div ng-controller="myController"&gt;
            &lt;input type="text" ng-model="format"/&gt;
            &lt;div&gt;Time format is: {{format}}&lt;/div&gt;
            &lt;div&gt;Current time is: &lt;span my-current-time="format"&gt;&lt;/span&gt;&lt;/div&gt;
        &lt;/div&gt;
</pre>
<p>We have also moved our directive to it&#8217;s own feature directory giving us another module that we can reuse in other applications.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
        // Register the 'myCurrentTime' directive factory method.
        // We inject $timeout and dateFilter service since the factory method is DI.
        angular.module('time', []).directive('myCurrentTime', function($timeout, dateFilter) {
            // return the directive link function. (compile function not needed)
            return function(scope, element, attrs) {
                var format,  // date format
                    timeoutId; // timeoutId, so that we can cancel the time updates
        
                // used to update the UI
                function updateTime() {
                    element.text(dateFilter(new Date(), format));
                }
        
                // watch the expression, and update the UI on change.
                scope.$watch(attrs.myCurrentTime, function(value) {
                    format = value;
                    updateTime();
                });
        
                // schedule update in one second
                function updateLater() {
                    // save the timeoutId for canceling
                    timeoutId = $timeout(function() {
                        updateTime(); // update DOM
                        updateLater(); // schedule another update
                    }, 1000);
                }
        
                // listen on DOM destroy (removal) event, and cancel the next UI update
                // to prevent updating time after the DOM element was removed.
                element.bind('$destroy', function() {
                    $timeout.cancel(timeoutId);
                });
        
                updateLater(); // kick off the UI update process.
            }
        });
</pre>
<p>Finally, we have our index.html file which loads our source and instantiates our app. Notice that we have a script tag for each of our source files and that we are using the ng-include directive to load our view&#8217;s template.</p>
<pre class="dontquote prettyprint lang-html linenumstrigger linenums">
        &lt;!DOCTYPE html&gt;
        &lt;html ng-app="myApp"&gt;
        &lt;head&gt;
            &lt;title&gt;&lt;/title&gt;
            &lt;script src="lib/angular/angular.js" type="text/javascript"&gt;&lt;/script&gt;
            &lt;script src="app/app.js" type="text/javascript"&gt;&lt;/script&gt;
            &lt;script src="myView/my-view-controller.js" type="text/javascript"&gt;&lt;/script&gt;
            &lt;script src="time/time-directive.js" type="text/javascript"&gt;&lt;/script&gt;
        &lt;/head&gt;
        &lt;body&gt;
        &lt;div ng-include src="'myView/my-view-partial.html'"&gt;&lt;/div&gt;
        &lt;/body&gt;
        &lt;/html&gt;
</pre>
<h2>Use What Works Best for Your App</h2>
<p>So we&#8217;ve covered several patterns that can be used to organize your source code, which one you use is up to you. Below are a couple of quick guidelines for writing different types of apps or re-usable components:</p>
<ul>
<li>Directives and Components &#8211; If possible try to keep your code to a single module and single source file. If you have templates that your directive or component depends upon, either provide an attribute or method that allows end users to provide a templat Url or include a second JavaScript file that loads the templates via code and adds them to the template cache.
</li>
<li>Re-Usable Feature Modules &#8211; Use the Package by Feature pattern to keep everything in a single directory that can easily be added to a project. Whether you use separate template files or include them in a source file is up to you, lean towards what works best if the module templates need to be tailored for use in the app they are added to. If you plan on making the module deployable via Bower or npm, plan on including your unit tests so end users can use them to ensure everything works as plan.
</li>
<li>Simple Apps &#8211; Use a single source module and source file to reduce the number of files that need to be loaded at run time. If you have multiple templates in your app, consider putting them into the index.html file and use ng-show, ng-hide or ng-switch to display them as needed.
</li>
<li>Large Complex Apps &#8211; Use the Package by Feature pattern to structure your source code into modules and then use the Package by Layer pattern for your source files.
</li>
</ul>
<h2>Where Do I Put My Unit Tests?</h2>
<p>Another question that comes up when talking about source code structure is &#8220;Where do I put my unit tests?&#8221;</p>
<p>I&#8217;m a believer that unit tests should be under a seperate folder called &#8216;unittests&#8217; that has the same directory structure as your app. If you structure your app by feature, then your unit tests should also be structured by feature. This helps with maintenance since the directory structure is the same as the source code&#8217;s structure.</p>
<p>The only time to I would include the unit tests with the actual source files is if you are create a package that will be distributed by a package manager such as Bower or npm. Then I think it&#8217;s more important so the end user has a way to validate your directive or component works as intended.</p>
<p>What you do is ultimately up to you. Those are the decisions that you should make based on your team&#8217;s workflow.</p>
<h2>The Wrap Up</h2>
<p>In this article I&#8217;ve covered a couple of different patterns that you can use to organize your AngularJS source code and how modules can be used to help you organize your code and it&#8217;s dependencies. Hopefully, this helps you come up with a project structure that works best for you and your team.</p>
<h2>Source Code</h2>
<p>You can find all of the source code for this article on my GitHub page at <a href="https://github.com/lavinjj/angularjs-modules-for-great-justice" >https://github.com/lavinjj/angularjs-modules-for-great-justice</a></p>
]]></content:encoded>
			<wfw:commentRss>http://codingsmackdown.tv/blog/2013/04/19/angularjs-modules-for-great-justice/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Using Response Interceptors to Show and Hide a Loading Widget</title>
		<link>http://codingsmackdown.tv/blog/2013/01/02/using-response-interceptors-to-show-and-hide-a-loading-widget/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-response-interceptors-to-show-and-hide-a-loading-widget</link>
		<comments>http://codingsmackdown.tv/blog/2013/01/02/using-response-interceptors-to-show-and-hide-a-loading-widget/#comments</comments>
		<pubDate>Wed, 02 Jan 2013 17:44:28 +0000</pubDate>
		<dc:creator>Jim Lavin</dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[code.explode]]></category>
		<category><![CDATA[Application Code]]></category>
		<category><![CDATA[Array]]></category>
		<category><![CDATA[Authentication]]></category>
		<category><![CDATA[Exception Handling]]></category>
		<category><![CDATA[Interceptor]]></category>
		<category><![CDATA[Interceptors]]></category>
		<category><![CDATA[Promise]]></category>
		<category><![CDATA[Response Interceptor]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[Yeasts]]></category>

		<guid isPermaLink="false">http://codingsmackdown.tv/?p=141</guid>
		<description><![CDATA[AngularJS provides extension points which allow you to intercept responses to http requests before they are handed over to the application code. You can use these extension points to provide global exception handling, authentication, or any other type of pre-processing you might need in your app. In this article I&#8217;m going to show you how [...]]]></description>
				<content:encoded><![CDATA[<p>AngularJS provides extension points which allow you to intercept responses to http requests before they are handed over to the application code. You can use these extension points to provide global exception handling, authentication, or any other type of pre-processing you might need in your app. In this article I&#8217;m going to show you how you can use a response interceptor to turn a loading widget on and off as your http requests are made and completed.</p>
<p><span id="more-141"></span></p>
<h2>The App Overview</h2>
<p>I&#8217;ve created a simple app that displays a list of different yeast strains used in home brewing. I&#8217;ve stored the list of yeast strains in a MongoDB collection out on mongolabs.com and I am using the Promise-aware MongoLab $resource for AngularJS by Pawel Kozlowski out on GitHub at <a href="https://github.com/pkozlowski-opensource/angularjs-mongolab-promise" target="_blank">https://github.com/pkozlowski-opensource/angularjs-mongolab-promise</a> to retrieve the collection.</p>
<p>I&#8217;ve also added a simple filter that allows us to page through the data to make the data a little easier to deal with.</p>
<p>If you look at code it&#8217;s pretty straight forward, the controller makes a call to the data resource which in turn queries the mongolab collection that we assign to an internal array that is used in the ng-repeat to populate the page.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
'use strict';

// Declare app level module which depends on filters, and services
var app = angular.module('myApp', ['mongolabResourceHttp', 'data.services', ]);

app.filter('startFrom', function () {
        return function (input, start) {
            start = +start; //parse to int
            return input.slice(start);
        }
    });

function myController($scope, YeastResource) {
    $scope.yeasts = [];
    $scope.currentPage = 0;
    $scope.pageSize = 10;

    $scope.numberOfPages = function () {
        return Math.ceil($scope.yeasts.length / $scope.pageSize);
    };

    $scope.init = function() {
        YeastResource.query({}, {sort: {Type: 1, Name: 1}}).then(function(yeast){
            $scope.yeasts = yeast;
        });
    };

    $scope.init();
}
</pre>
<p>Below is the HTML Mark up used to display the data on the page. It&#8217;s pretty straight forward as well. The only thing to note is how the buttons are used to change the currentPage scope variable to page through the data.</p>
<pre class="dontquote prettyprint lang-html linenumstrigger linenums">
&lt;div class="container-fluid" ng-controller="myController"&gt;
    &lt;div class="row-fluid"&gt;
        &lt;h2&gt;HTTP Interceptor Example&lt;/h2&gt;
    &lt;/div&gt;
    &lt;div class="row-fluid" &gt;
        &lt;div class="span1"&gt;Name&lt;/div&gt;
        &lt;div class="span1"&gt;Type&lt;/div&gt;
        &lt;div class="span1"&gt;Form&lt;/div&gt;
        &lt;div class="span1"&gt;Laboratory&lt;/div&gt;
        &lt;div class="span3"&gt;Best For&lt;/div&gt;
        &lt;div class="span5"&gt;Notes&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="row-fluid" ng-repeat="yeast in yeasts | startFrom:currentPage*pageSize | limitTo:pageSize"&gt;
        &lt;div class="span1"&gt;{{yeast.Name}}&lt;/div&gt;
        &lt;div class="span1"&gt;{{yeast.Type}}&lt;/div&gt;
        &lt;div class="span1"&gt;{{yeast.Form}}&lt;/div&gt;
        &lt;div class="span1"&gt;{{yeast.Laboratory}}&lt;/div&gt;
        &lt;div class="span3"&gt;{{yeast.BestFor}}&lt;/div&gt;
        &lt;div class="span5"&gt;{{yeast.Notes}}&lt;/div&gt;
    &lt;/div&gt;
    &lt;hr /&gt;
    &lt;div class="well"&gt;
        &lt;button ng-disabled="currentPage == 0" ng-click="currentPage=0"&gt;
            First
        &lt;/button&gt;
        &lt;button ng-disabled="currentPage == 0" ng-click="currentPage=currentPage-1"&gt;
            Previous
        &lt;/button&gt;
        &lt;span ng-bind="currentPage+1"&gt;1&lt;/span&gt;/&lt;span ng-bind="numberOfPages()"&gt;Loading..&lt;/span&gt;
        &lt;button ng-disabled="currentPage >= yeasts.length/pageSize - 1" ng-click="currentPage=currentPage+1"&gt;
            Next
        &lt;/button&gt;
        &lt;button ng-disabled="currentPage >= yeasts.length/pageSize - 1" ng-click="currentPage=numberOfPages()-1"&gt;
            Last
        &lt;/button&gt;
    &lt;/div&gt;
&lt;/div&gt;
</pre>
<h2>Adding a Loading Widget</h2>
<p>First let&#8217;s define our loading widget. We&#8217;ll add a DIV to the HTML Mark up and set the id to loadingWidget so we can show and hide it in our response interceptor. All the loading widget does is wrap an image tag that contains our animated gif and the word Loading. By default we use an in-line style to set the DIV to display: none so it will not be visible until we set it visible.</p>
<pre class="dontquote prettyprint lang-html linenumstrigger linenums">
&lt;div class="container-fluid" ng-controller="myController"&gt;
    &lt;div id="loadingWidget" class="row-fluid ui-corner-all" style="padding: 0 .7em; display: none;"&gt;
        &lt;div class="loadingContent"&gt;
            &lt;p&gt;
                &lt;img alt="Loading  Content" src="images/ajax-loader.gif" /&gt;&nbsp;Loading
            &lt;/p&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="row-fluid"&gt;
        &lt;h2&gt;HTTP Interceptor Example&lt;/h2&gt;
    &lt;/div&gt;
    &lt;div class="row-fluid" &gt;
        &lt;div class="span1"&gt;Name&lt;/div&gt;
        &lt;div class="span1"&gt;Type&lt;/div&gt;
        &lt;div class="span1"&gt;Form&lt;/div&gt;
        &lt;div class="span1"&gt;Laboratory&lt;/div&gt;
        &lt;div class="span3"&gt;Best For&lt;/div&gt;
        &lt;div class="span5"&gt;Notes&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="row-fluid" ng-repeat="yeast in yeasts | startFrom:currentPage*pageSize | limitTo:pageSize"&gt;
        &lt;div class="span1"&gt;{{yeast.Name}}&lt;/div&gt;
        &lt;div class="span1"&gt;{{yeast.Type}}&lt;/div&gt;
        &lt;div class="span1"&gt;{{yeast.Form}}&lt;/div&gt;
        &lt;div class="span1"&gt;{{yeast.Laboratory}}&lt;/div&gt;
        &lt;div class="span3"&gt;{{yeast.BestFor}}&lt;/div&gt;
        &lt;div class="span5"&gt;{{yeast.Notes}}&lt;/div&gt;
    &lt;/div&gt;
    &lt;hr /&gt;
    &lt;div class="well"&gt;
        &lt;button ng-disabled="currentPage == 0" ng-click="currentPage=0"&gt;
            First
        &lt;/button&gt;
        &lt;button ng-disabled="currentPage == 0" ng-click="currentPage=currentPage-1"&gt;
            Previous
        &lt;/button&gt;
        &lt;span ng-bind="currentPage+1"&gt;1&lt;/span&gt;/&lt;span ng-bind="numberOfPages()"&gt;Loading..&lt;/span&gt;
        &lt;button ng-disabled="currentPage >= yeasts.length/pageSize - 1" ng-click="currentPage=currentPage+1">
            Next
        &lt;/button>
        &lt;button ng-disabled="currentPage >= yeasts.length/pageSize - 1" ng-click="currentPage=numberOfPages()-1">
            Last
        &lt;/button>
    &lt;/div>
&lt;/div>
</pre>
<p>Next let&#8217;s add a response interceptor to show and hide a loading widget while our query is being made against mongolab.com.</p>
<p>To do this we&#8217;ll add a configuration item to our app.js file that will define the response interceptor.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
app.config(['$httpProvider', function ($httpProvider) {
    var $http,
        interceptor = ['$q', '$injector', function ($q, $injector) {
            var error;

            function success(response) {
                // get $http via $injector because of circular dependency problem
                $http = $http || $injector.get('$http');
                if($http.pendingRequests.length < 1) {
                    $('#loadingWidget').hide();
                }
                return response;
            }

            function error(response) {
                // get $http via $injector because of circular dependency problem
                $http = $http || $injector.get('$http');
                if($http.pendingRequests.length < 1) {
                    $('#loadingWidget').hide();
                }
                return $q.reject(response);
            }

            return function (promise) {
                $('#loadingWidget').show();
                return promise.then(success, error);
            }
        }];

    $httpProvider.responseInterceptors.push(interceptor);
}]);
</pre>
<p>The interceptor will be called prior to any application code, so we need to provide functions to intercept the success and error callbacks along with a function that is used to insert our success and error functions into the call hierarchy of the promise returned from the call to $http.</p>
<p>We also need to push our interceptor onto the array of response interceptors maintained by the $httpProvider so each call to the $http service calls our code.</p>
<p>Both the success and error functions are very similar, each one gets the $http service via the $injector service to avoid circular dependencies and then checks to see if the number of pending requests is less than one, if so the code hides the loadingWidget element. The Success method then returns the response and the Error method calls reject with the response to indicate the call failed.</p>
<p>The third method shows the loadingWidget and returns the promise with the Success and Error methods inserted into the response chain.</p>
<p>Now every time a call to the $http service is made our interceptor will be called and will display the loadingWidget and hide it accordingly.</p>
<p>Below is the full code of our app.js file:</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
'use strict';

// Declare app level module which depends on filters, and services
var app = angular.module('myApp', ['mongolabResourceHttp', 'data.services', ]);

app.config(['$httpProvider', function ($httpProvider) {
    var $http,
        interceptor = ['$q', '$injector', function ($q, $injector) {
            var error;

            function success(response) {
                // get $http via $injector because of circular dependency problem
                $http = $http || $injector.get('$http');
                if($http.pendingRequests.length < 1) {
                    $('#loadingWidget').hide();
                }
                return response;
            }

            function error(response) {
                // get $http via $injector because of circular dependency problem
                $http = $http || $injector.get('$http');
                if($http.pendingRequests.length < 1) {
                    $('#loadingWidget').hide();
                }
                return $q.reject(response);
            }

            return function (promise) {
                $('#loadingWidget').show();
                return promise.then(success, error);
            }
        }];

    $httpProvider.responseInterceptors.push(interceptor);
}]);

app.filter('startFrom', function () {
        return function (input, start) {
            start = +start; //parse to int
            return input.slice(start);
        }
    });

function myController($scope, YeastResource) {
    $scope.yeasts = [];
    $scope.currentPage = 0;
    $scope.pageSize = 10;

    $scope.numberOfPages = function () {
        return Math.ceil($scope.yeasts.length / $scope.pageSize);
    };

    $scope.init = function() {
        YeastResource.query({}, {sort: {Type: 1, Name: 1}}).then(function(yeast){
            $scope.yeasts = yeast;
        });
    };

    $scope.init();
}
</pre>
<h2>The Wrap Up</h2>
<p>This article shows a simple way to use response interceptors to display and hide a loading widget each time the $http service requests data from a server. It also showed how you can plug your code into the $http service pipeline to provide cross cutting functionality for your AngularJS Apps. To learn more about response interceptors check out the AngularJS $http service API documentation at <a href="http://docs.angularjs.org/api/ng.$http" target="_blank">http://docs.angularjs.org/api/ng.$http</a></p>
<p>Hopefully, this article helps you to see some of the extensibility points provided by the AngularJS library and helps you think of ways you can code for cross cutting concerns using such extension points.</p>
<p>Code for this example can be found on GitHub at <a href=" https://github.com/lavinjj/angularjs-spinner" target="_blank">https://github.com/lavinjj/angularjs-spinner</a></p>
<p>As always, drop me a comment on other AngularJS topics you’d like to see more tutorials on.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong>Edit:</strong>&nbsp;&nbsp;I have provided an updated version of the above example that works better. Please see my new post <a href="http://codingsmackdown.tv/blog/2013/04/20/using-response-interceptors-to-show-and-hide-a-loading-widget-redux/">Using Response Interceptors to Show and Hide a Loading Widget: Redux</a></p>
]]></content:encoded>
			<wfw:commentRss>http://codingsmackdown.tv/blog/2013/01/02/using-response-interceptors-to-show-and-hide-a-loading-widget/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mocking Promises in Unit Tests</title>
		<link>http://codingsmackdown.tv/blog/2012/12/28/mocking-promises-in-unit-tests/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mocking-promises-in-unit-tests</link>
		<comments>http://codingsmackdown.tv/blog/2012/12/28/mocking-promises-in-unit-tests/#comments</comments>
		<pubDate>Fri, 28 Dec 2012 18:45:40 +0000</pubDate>
		<dc:creator>Jim Lavin</dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[code.explode]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[$http]]></category>
		<category><![CDATA[$q]]></category>
		<category><![CDATA[Code Patterns]]></category>
		<category><![CDATA[Controller Code]]></category>
		<category><![CDATA[Data Error]]></category>
		<category><![CDATA[Error Function]]></category>
		<category><![CDATA[Jasmine]]></category>
		<category><![CDATA[Partials]]></category>
		<category><![CDATA[Promises]]></category>
		<category><![CDATA[Scope]]></category>
		<category><![CDATA[Service Factory]]></category>
		<category><![CDATA[Unit Tests]]></category>
		<category><![CDATA[Writing Services]]></category>

		<guid isPermaLink="false">http://codingsmackdown.tv/?p=127</guid>
		<description><![CDATA[If you&#8217;ve spent some time writing services in AngularJS that front-end Web APIs, you have probably used the $http service. One of the prevalent code patterns that tends to develop involves calling the .then() method on the promise that is returned from the various $http methods. This in effect waits to execute code until the [...]]]></description>
				<content:encoded><![CDATA[<p>If you&#8217;ve spent some time writing services in AngularJS that front-end Web APIs, you have probably used the $http service. One of the prevalent code patterns that tends to develop involves calling the .then() method on the promise that is returned from the various $http methods. This in effect waits to execute code until the asynchronous request returns and the promise is resolved.</p>
<p>The more complicated the Web API you are interacting with, the more your controller code tends to end up with several bits of code as shown below:</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
    user.requestCurrentUser().then(function() {
        $scope.currentUser = user.getCurrentUser();
    });
</pre>
<p>Testing this code can be a bit problemsome for newcomers to AngularJS. This article shows a simple way to mock your services to provide similar functionality so you can unit test your controllers that contain these type of code patterns.</p>
<p><span id="more-127"></span></p>
<h2>A Simple Service that uses $http</h2>
<p>To demonstrate how to test a controller that contains the above code pattern, we first need to create a simple service which uses the $http service and returns the promise from the $http() method.</p>
<p>Below is a simple service that provides an array which holds the returned data and a single method requestPeople which requests the data from the server, returns a promise and then updates the array with the returned data once the request completes:</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
    angular.module('people.service', []).
        factory('people', ['$http', function($http) {
            var people = {
                peopleStore = [],

                requestPeople: function() {
                    var url = '/data/people.json';

                    return $http.get(url).success(function(data) {
                        peopleStore = data;
                    }).error(function() {
                        peopleStore = [];
                    });
                }
            };

            return people;
        }]);
</pre>
<p>We will next create a simple app and controller that will use the service.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
    angular.module('sampleApp', ['people.service']).
        config(['$routeProvider', function($routeProvider) {
            $routeProvider.
                when('/', {templateUrl:'partials/peoplelist.html', controller:PeopleListController);
        }]);


    function PeopleListController($scope, people) {
        $scope.peopleList = [];

        $scope.init = function() {
            people.requestPeople().then(function() {
                $scope.peopleList = people.peopleStore;
            });
        };
    }
</pre>
<p>The controller&#8217;s init method calls the requestPeople() method of the service and chains a call to the then() method of the returned promise. Once the promise is resolved, the controller populates the peopeList in it&#8217;s scope with the data stored in the service.</p>
<p>And below is the contents of the peoplelist.html file, which displays the people using a ng-repeat:</p>
<pre class="dontquote prettyprint lang-html linenumstrigger linenums">
    &lt;div class="container-fluid"&gt;
        &lt;div class="row-fluid"&gt;
            &lt;h2&gt;People List&lt;/h2&gt;
        &lt;/div&gt;
        &lt;div class="row-fluid"&gt;
            &lt;div class="well"&gt;
                &lt;div class="span1"&gt;Name&lt;/div&gt;
                &lt;div class="span2"&gt;Email&lt;/div&gt;
                &lt;div class="span3"&gt;Bio&lt;/div&gt;
                &lt;div class="span1"&gt;&lt;a href="#/new"&gt;&lt;span class="icon icon-plus"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/div&gt;
            &lt;div class="row-fluid" ng-repeat="person in PeopleList"&gt;
                &lt;div class="span1" ng-bind="person.FirstName + ' ' + person.LastName"&gt;&lt;/div&gt;
                &lt;div class="span2" ng-bind="person.Email"&gt;&lt;/div&gt;
                &lt;div class="span3" ng-bind="person.Bio"&gt;&lt;/div&gt;
                &lt;div class="span1"&gt;&lt;a href="#/edit/{{$index}}"&gt;&lt;span class="icon icon-edit"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
</pre>
<h2>Mocking Out the Service</h2>
<p>Now that we have our code, let&#8217;s write some unit tests for the controller.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
    describe('People List Controller', function() {
        var scope;
        var peopleService;
        var controller;
        var q;
        var deferred;

        // define the mock people service
        beforeEach(function() {
            peopleService = {
                peopleStore = [{FirstName:"Jim", LastName:"Lavin", Email:"jlavin@jimlavin.net", Bio:"Creator and Host of Coding Smackdown TV"}],

                requestPeople: function() {
                    deferred = q.defer();
                    return deferred.promise;
                }
            };
        });

        // inject the required services and instantiate the controller
        beforeEach(inject(function($rootScope, $controller, $q) {
            scope = $rootScope.$new();
            q = $q;
            controller = $controller(PeopleListController, { $scope:scope, people: peopleService });
        }));

        it('should call requestPeople on the people service when init is called' function() {
            spyOn(peopleService, 'requestPeople').andCallThrough();

            scope.init();

            deferred.resolve();

            scope.$root.$digest();

            expect(peopleService.requestPeople).toHaveBeenCalled();
        });

        it('should populate the peopleList when init is called' function() {
            scope.init();

            deferred.resolve();

            scope.$root.$digest();

            expect(scope.peopleList).not.toBe([]);
        });
    });
</pre>
<p>Although the unit test may seem to be a bit complicated it is rather straight forward.</p>
<p>Initially, we create variables to hold the scope, mock service, a reference to the $q service and a reference of the deferred object created when we call q.defer() in our mock service.</p>
<p>We need to hold on to a reference to the $q service from AngularJS, so that we can call it when ever the requestPeople method of our mock service is called.</p>
<p>We&#8217;ll also need to hold on to the deferred object created by the call to q.defer() so we can resolve the promise, which in turn will execute the then() clause in our controller&#8217;s code.</p>
<p>Next, we define our mock service in a beforeEach() call so that each time a test is executed we have a clean version of our mock service.</p>
<p>Our mock service is pretty simple. First we make sure that at least each of the properites and methods the controller will access is defined, in this case that would be peopleStore and requestPeople. We then pre-populate the peopleStore with some default data. Finally, we mock out the requestPeople method by creating a deferred object, store the deferred object off and return the promise.</p>
<p>Next we make another call to beforeEach() that injects the services we need from AngularJS, creates the scope for the controller, stores off the $q service so our mock service can call it and then we finally instantiate the PeopleListController passing in the scope and our mock service.</p>
<p>Now we can go about creating our unit test scenarios.</p>
<p>In the first scenario we&#8217;ll check to see if the init method of the controller calls the requestPeople method of the people service. To do this we&#8217;ll use Jasmine&#8217;s spyOn() method which intercepts the call to the requestPeople method and tracks how many times the method is called. We also need to tell Jasmine what to do after it intercepts the call, we can either have it return a value, call a different function or have it call through to the original implementation. In our case we&#8217;ll just have it call through to the original implementation of our mock service.</p>
<p>Next we&#8217;ll call the init method on the controller, which should invoke our mock service that in turns creates the deferred object and stores it off and returns the promise to the controller which then waits for the promise to be resolved.</p>
<p>We then resolve the promise by calling deferred.resolve() and since we are outside the AngularJS world we have to call digest() on the scope&#8217;s root to have AngularJS invoke the then() clause in our controller. Once this happens the code in the then() clause of our controller will be executed and we can execute our assertions to make sure the code performed as we expected it to, in this case we check to see if the the requestPeople method of the service was called.</p>
<p>In the second scenario, we want to make sure that the then() clause was called and that the controller populated the peopleList on it&#8217;s scope with the data from the service. This is done in a similar manner, but since we do not care if the requestPeople method is called, we leave out the call to spyOn() and just call the controller&#8217;s init method, resolve the promise and call digest on the root scope so the then() clause is executed. Finally, we check to see that the peopleList in the controller&#8217;s scope is populated with the test data.</p>
<p>You could use the same scenario to handle reject processing as well by calling deferred.reject() instead of deferred.resolve().</p>
<p>Below is a jsFiddle that has a working example of the code above:</p>
<p><iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/lavinjj/zWkzP/embedded/" allowfullscreen="allowfullscreen" frameborder="0"></iframe></p>
<h2>The Wrap Up</h2>
<p>So in this article, I covered how to build a simple service that uses the $http service from AngularJS; how to use a promise returned from the $http service to wait until the asynchronous call completes by using the then() method of the promise, as well as how to write a mock service that returns promises so you can unit test your code.</p>
<p>Hopefully, this article will help you to easily write unit tests for your controllers which contain code that uses promises and get you over some of the hurdles of learning a new framework.</p>
<p>As always, drop me a comment on other AngularJS topics you’d like to see more tutorials on.</p>
]]></content:encoded>
			<wfw:commentRss>http://codingsmackdown.tv/blog/2012/12/28/mocking-promises-in-unit-tests/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>What Led Me to AngularJS</title>
		<link>http://codingsmackdown.tv/blog/2012/12/19/what-led-me-to-angularjs/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=what-led-me-to-angularjs</link>
		<comments>http://codingsmackdown.tv/blog/2012/12/19/what-led-me-to-angularjs/#comments</comments>
		<pubDate>Wed, 19 Dec 2012 22:10:28 +0000</pubDate>
		<dc:creator>Jim Lavin</dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[code.explode]]></category>
		<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://codingsmackdown.tv/?p=118</guid>
		<description><![CDATA[I am sure many of you reading this come from an ASP.NET background or are familiar with how ASP.NET web apps work with the constant post back to the server to update data, process it and redirect the user to the next step of the process. It has worked for the past 10 years and [...]]]></description>
				<content:encoded><![CDATA[<p>I am sure many of you reading this come from an ASP.NET background or are familiar with how ASP.NET web apps work with the constant post back to the server to update data, process it and redirect the user to the next step of the process. It has worked for the past 10 years and it has worked well. But, there are better ways to interact with the server and update the user.</p>
<p>The growth of JavaScript, jQuery and frameworks such as Backbone, Knockout, and Ember have done an enormous amount for improving client side interaction and asynchronous communications with the business logic back-end. </p>
<p>That is where the app I&#8217;m maintaining is, we use ASP.NET REST based services with jQuery to manage user interaction and communicate with the back end. It works and its performance is OK, but it’s not great and it really doesn&#8217;t take advantage of today&#8217;s browser capabilities.</p>
<p><span id="more-118"></span></p>
<p>As I started to research the latest frameworks appearing on the scene I realized, that more of our client side logic could be included in a Single Page Application giving an even better client experience. So, we slowly started migrating logic from the server-side ASP.NET pages to the client using Knockout and ASP.NET MVC into a quasi-Single Page Application.</p>
<p>We practiced the Model-View-Controller partitioning of concerns and we ended up with a faster, nicer and richer client side experience, but the more code I wrote, the more I noticed that I was repeating code and HTML all over the place. I was also adding additional code to take JSON objects and convert them into model objects the framework could bind to and manage. </p>
<p>Then one day as I explained our app to a new developer, I realized that two-thirds of our code was there to just interact with the framework. Only a third of the code had anything to do with our actual business logic. I knew there had to be a better way.</p>
<p>That&#8217;s when I came across a post on Google+ about AngularJS and I spent some time checking it out, it looked promising, and it had many of the features I was needing without having to bring in third party libraries from all over the place.</p>
<p>Right from the start the AngularJS examples show you how to bind your model data into your HTML content with very simple markup. There’s no need for special objects to handle the data binding for you and I was able to do away with all of the code to translate our data into objects the framework could interact with, AngularJS just used the data returned from our services without issue. </p>
<p>AngularJS also provides a way to extend your HTML markup through Directives and Filters. With Directives you can create your own HTML tags that binds to your data and outputs markup that automatically updates whenever the data changes. </p>
<p>Filters provide you a way to transform data into whatever subset of data or format you might need. The framework comes standard with filters for currency, data, lowercase, number plus several more to help order your data or break it into subsets based on an easy JSON based syntax.</p>
<p>The Route Provider in AngularJS provides routing and deep linking support important for Single Page Apps. You can define your routes, the templates to display and which controllers to load. Then by using the ng-view directive on your page, your templates will be loaded and displayed automatically without you having to write a single line of code.</p>
<p>AngularJS also includes a whole host of functionality for Form Validation. You can declare validation rules in your form’s mark up and then query the form in your controller to ensure your rules are met before continuing on with your logic. Using the data-binding you can dynamically display errors as they occur giving your end user feedback right when they need it.</p>
<p>All throughout the AngularJS Framework the concept of using services to handle cross cutting concerns is evident. There are services to handle exceptions, services to make asynchronous calls to your back-end services, services to interact with the DOM and mock services to help in testing.</p>
<p>As you build controllers or other services, AngularJS provides you with a built in dependency injection mechanism to get the services your code depends upon without a lot of coding and configuration. The dependency injection in AngularJS allows for extensibility, if you need to replace a service with your own service, all you need to do is declare it in your code and your service will be invoked instead of the framework version.</p>
<p>Finally AngularJS was built with testability in mind. AngularJS provides a full mock library to allow you to isolate your code for testing. There is even an entire portion of the framework devoted to end to end testing.</p>
<p>From my experience working with AngularJS over the past couple of months, I think the following words from the AngularJS site sums it all up. </p>
<p>`Write less code, go have beer sooner.`</p>
]]></content:encoded>
			<wfw:commentRss>http://codingsmackdown.tv/blog/2012/12/19/what-led-me-to-angularjs/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Localizing Your AngularJS App</title>
		<link>http://codingsmackdown.tv/blog/2012/12/14/localizing-your-angularjs-app/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=localizing-your-angularjs-app</link>
		<comments>http://codingsmackdown.tv/blog/2012/12/14/localizing-your-angularjs-app/#comments</comments>
		<pubDate>Sat, 15 Dec 2012 03:39:54 +0000</pubDate>
		<dc:creator>Jim Lavin</dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[code.explode]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Filter]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Localization]]></category>
		<category><![CDATA[Service]]></category>

		<guid isPermaLink="false">http://codingsmackdown.tv/?p=104</guid>
		<description><![CDATA[Overview If you plan on being in the Web App development business for any amount of time, sooner or later you are going to be faced with building an app that supports multiple languages. When this time comes you’ll be faced with the localization challenge that so many developers before you have faced. To solve [...]]]></description>
				<content:encoded><![CDATA[<h2>Overview</h2>
<p>If you plan on being in the Web App development business for any amount of time, sooner or later you are going to be faced with building an app that supports multiple languages. When this time comes you’ll be faced with the localization challenge that so many developers before you have faced.</p>
<p>To solve this challenge some developers have built entire localization frameworks and libraries, while others have resorted to re-creating their entire site in the desired language and redirecting users based on their browser culture.</p>
<p>In this article, I’ll show you an easy way to use an AngularJS Service and Filter to pull localized strings from a resource file and populate the page content based on the user’s browser culture.</p>
<p><span id="more-104"></span></p>
<h2>Architecture</h2>
<p>Our solution is going to be based on a simple architecture. We will use localized resource files for each language we want to support. We will also have a default resource file that will be used to fall back to the site’s native language if a given user’s language is not supported.</p>
<p>We will build an AngularJS Service that will be responsible for checking the user’s browser culture and requesting the appropriate resource based on the language. If the resource file does not exist it will request the default resource file and use it.</p>
<p>The service will also provide a lookup method that will return a localized string for a given key from the loaded resource file.<br />
Since the service may not be called directly by a controller or app module we’ll also provide a mechanism for the service to initialize itself, load the appropriate localized resource file and prepare itself to handle requests.</p>
<p>We will also build an AngularJS Filter that can be used in your HTML as a front-end to the localization service. Using the filter will help you keep your code clean and keep you controllers from having to know about the localization service.</p>
<p>To use the filter you can use an expression such as; {{&#8216;_FormControllerTitle_&#8217; | i18n}} if you want to inject the localized string directly into a tag or you can use the ng-bind=&#8217;_FormControllerTitle_&#8217; | i18n” method to inject the localized string into an element, when AngluarJS compiles and links the DOM.</p>
<p>Finally let’s talk a bit about how we’ll store the localized data for the service. Since our service will be requesting the resource files once the app in bootstrapped, we need a place to store them. To keep the overall size of the service small I thought it was best not to embed the strings in the service class, but put them in directory off the root of the site named i18n. This follows the same pattern you see with several libraries where the localized resources are in a directory co-located with the module.</p>
<p>The files also have a specific file naming format; resources-locale_xx-yy.js where xx is the language identifier and yy is the country identifier. So resources-locale_en-US.js would mean the file is for English, United States and resources-locale_es_es.js would mean the file is for Spanish, Spain.</p>
<p>There is one more file naming convention we’ll use and that is for the default resource file. For the default file that will be loaded is a language resource file for language does not exist on your system it will be named resources-locale_default.js</p>
<p>The format of the language resource file is simple. Since we only really need a few pieces of information I’ve kept it to key, value and description. This way if you need to hand the file off to someone for translation they’ll have a general description of what the test is for.</p>
<p>This format will also help other developers on the project. When they are getting ready to add a new string resource they’ll be able to search the file to see if maybe there is already a string they can use. This comes in real handy for buttons, table headers, etc.</p>
<p>Below is an example of the file format:</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
[
    {
        "key":"_Greeting_",
        "value":"Site localization example using the resource localization service",
        "description":"Home page greeting text"
    },
    {
        "key":"_HomeTitle_",
        "value":"Resource Localization Service",
        "description":"Home page title text"
    }
]
</pre>
<h2>Building the Service</h2>
<p>So now that we have covered the architecture of our solution, let’s get to writing some code.</p>
<p>Let’s start by creating a new JavaScript file and calling it localize.js</p>
<p>Then let’s add the skeleton to define both the module and the service.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
'use strict';

/*
 * An AngularJS Localization Service
 *
 * Written by Jim Lavin
 * http://codingsmackdown.tv
 *
 */

angular.module('localization', []).
    factory('localize', function ($http, $rootScope, $window, $filter) {

    });
</pre>
<p>We start off by calling angular.module which will define our module that we’ll name ‘localization’. Since our module does not depend on anything but the built in AngularJS service we will pass in an empty array to the method as well.</p>
<p>Then we chain a factory method off of the module to define our service which we’ll call ‘localize’ and add a function that will be used to define our service. You can see this in the code above.</p>
<p>Next we need to add the services the service is dependent on so Angular can inject them. This will be using the following services:</p>
<ul>
<li>$http – This will be used to retrieve the localized resource file from the web server.</li>
<li>$rootScope – This will be used to broadcast a message once the localized resource has been retrieved and loaded by the system. I’m using this is in case a controller or other service might use the service directly and needs to know when the service is ready.</li>
<li>$window – This will be used to find out the culture of the user’s browser, which we’ll use to request the appropriate resource file from the web server. There is an Angular service called $locale which should provide this information, but currently it seems to be hard coded to en-us from what I’ve experimented with and from what I’ve read over at Google Groups. If anyone has gotten this to work, please leave me a comment so I can revise the code to use the proper service.</li>
<li>$filter – This will be used to filter the dictionary array and return back only those resource objects that has the desired key the user is looking for.</li>
</ul>
<p>To add our dependencies and to ensure that any minification doesn’t muck them up, we are going to use the [] around our function to tell Angular what services we depend on. The revised code is below:</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
'use strict';

/*
 * An AngularJS Localization Service
 *
 * Written by Jim Lavin
 * http://codingsmackdown.tv
 *
 */

angular.module('localization', []).
    factory('localize', ['$http', '$rootScope', '$window', '$filter', function ($http, $rootScope, $window, $filter) {

    });
</pre>
<p>As you can see each one of the dependencies are specified as an array of strings with the service definition function last. This way Angular will know what to inject into our service without issue. We then also repeat the dependencies in our function declaration so they are visible to our service.</p>
<p>Now let’s define the service interface. We are going to expose two methods:</p>
<ul>
<li>initLocalizedResources – Responsible for loading the localized resource file from the server.</li>
<li>getLocalizedString – responsible for returning a localized string based on the given key.</li>
</ul>
<p>So now our service looks as follows:</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
'use strict';

/*
 * An AngularJS Localization Service
 *
 * Written by Jim Lavin
 * http://codingsmackdown.tv
 *
 */

angular.module('localization', []).
    factory('localize', ['$http', '$rootScope', '$window', '$filter', function ($http, $rootScope, $window, $filter) {

        initLocalizedResources:function() {

        },

        getLocalizedString:function(key) {

        }
    });
</pre>
<p>Now that we have defined our interface, let's implement the service and discuss what each function does.</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
'use strict';

/*
 * An AngularJS Localization Service
 *
 * Written by Jim Lavin
 * http://codingsmackdown.tv
 *
 */

angular.module('localization', []).
    factory('localize', ['$http', '$rootScope', '$window', '$filter', function ($http, $rootScope, $window, $filter) {
    var localize = {
        // use the $window service to get the language of the user's browser
        language:$window.navigator.userLanguage || $window.navigator.language,
        // array to hold the localized resource string entries
        dictionary:[],
        // flag to indicate if the service hs loaded the resource file
        resourceFileLoaded:false,

        successCallback:function (data) {
            // store the returned array in the dictionary
            localize.dictionary = data;
            // set the flag that the resource are loaded
            localize.resourceFileLoaded = true;
            // broadcast that the file has been loaded
            $rootScope.$broadcast('localizeResourcesUpdates');
        },

        initLocalizedResources:function () {
            // build the url to retrieve the localized resource file
            var url = '/i18n/resources-locale_' + localize.language + '.js';
            // request the resource file
            $http({ method:"GET", url:url, cache:false }).success(localize.successCallback).error(function () {
                // the request failed set the url to the default resource file
                var url = '/i18n/resources-locale_default.js';
                // request the default resource file
                $http({ method:"GET", url:url, cache:false }).success(localize.successCallback);
            });
        },

        getLocalizedString:function (value) {
            // default the result to an empty string
            var result = '';
            // check to see if the resource file has been loaded
            if (!localize.resourceFileLoaded) {
                // call the init method
                localize.initLocalizedResources();
                // set the flag to keep from looping in init
                localize.resourceFileLoaded = true;
                // return the empty string
                return result;
            }
            // amke sure the dictionary has valid data
            if ((localize.dictionary !== []) &#038;&#038; (localize.dictionary.length > 0)) {
                // use the filter service to only return those entries which match the value
                // and only take the first result
                var entry = $filter('filter')(localize.dictionary, {key:value})[0];
                // check to make sure we have a valid entry
                if ((entry !== null) &#038;&#038; (entry != undefined)) {
                    // set the result
                    result = entry.value;
                }
            }
            // return the value to the call
            return result;
        }
    };
    // return the local instance when called
    return localize;
} ]);
</pre>
<p>To begin with we declare the local variable localize that will be used as a wrapper for our object. We then need a couple of internal variables so we can store local data the service will use.</p>
<ul>
<li>language &#8211; stores the user&#8217;s browser language. We will use this value to build the Url in order to request the appropriate localized resource file.</li>
<li>dictionary &#8211; stores the localized resource file.</li>
<li>resourceFileLoaded &#8211; indicates if the service has loaded the localized resource file, and is used to self init the service if needed.</li>
</ul>
<p>I&#8217;ve also added a callback function that will be used when our http request succeeds. It will take the data retrieved from the web server and store it in the dictionary, update the init flag and broadcast that the localized resource file has been loaded.</p>
<p>The initLocalizedResources function takes the language we got from the user&#8217;s browser and creates a Url we can use to request the localized resource file from the web server. We also provide an error callback function should the request fail. By default we&#8217;ll assume there is no localized resource file and will request the default resource file.</p>
<p>The getLocalizedString function is called by consumers of the service to get the localized string for a specific key. By default we&#8217;ll return an empty string if the dictionary has not been loaded or there is no entry in the dictionary for the key.</p>
<p>Next, the function checks to see if the service has been initialized, if not it calls the initLocalizedResources function and then sets the init flag so we do not go into a continuous loop.</p>
<p>Finally, the function checks the dictionary for the key using the $filter service to retrieve the objects that match the filter parameters of key = value and then we further reduce the returned values by only taking the first item in the array. If we have a valid entry then the function returns the value and processing is complete.</p>
<h2>Building the Filter</h2>
<p>Now that we&#8217;ve finished with the service, let&#8217;s build the filter so we can easily use the service in our HTML.</p>
<p>First we&#8217;ll start off by chaining the filter definition off the factory definition by appending .filter() to the end of method. We&#8217;ll then define our filter by setting it&#8217;s name to &#8216;i18n&#8217; along with the filter definition function that will be used to return the filter when called.</p>
<p>Next since the filter will be making calls to the localization service on behalf of our app we need to add the &#8216;localize&#8217; service to our dependency list and ensure we include it in the filter definition function declaration.</p>
<p>The rest of the code for the filter is pretty simple since all we are doing is passing through the request to the localize service. so we are just going to return a function that calls the localize service with the given input.</p>
<p>That pretty much all we have to do. The final code for both the service and filter is given below:</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
'use strict';

/*
 * An AngularJS Localization Service
 *
 * Written by Jim Lavin
 * http://codingsmackdown.tv
 *
 */

angular.module('localization', []).
    factory('localize', ['$http', '$rootScope', '$window', '$filter', function ($http, $rootScope, $window, $filter) {
    var localize = {
        // use the $window service to get the language of the user's browser
        language:$window.navigator.userLanguage || $window.navigator.language,
        // array to hold the localized resource string entries
        dictionary:[],
        // flag to indicate if the service hs loaded the resource file
        resourceFileLoaded:false,

        successCallback:function (data) {
            // store the returned array in the dictionary
            localize.dictionary = data;
            // set the flag that the resource are loaded
            localize.resourceFileLoaded = true;
            // broadcast that the file has been loaded
            $rootScope.$broadcast('localizeResourcesUpdates');
        },

        initLocalizedResources:function () {
            // build the url to retrieve the localized resource file
            var url = '/i18n/resources-locale_' + localize.language + '.js';
            // request the resource file
            $http({ method:"GET", url:url, cache:false }).success(localize.successCallback).error(function () {
                // the request failed set the url to the default resource file
                var url = '/i18n/resources-locale_default.js';http://codingsmackdown.tv/?p=104&#038;preview=true
                // request the default resource file
                $http({ method:"GET", url:url, cache:false }).success(localize.successCallback);
            });
        },

        getLocalizedString:function (value) {
            // default the result to an empty string
            var result = '';
            // check to see if the resource file has been loaded
            if (!localize.resourceFileLoaded) {
                // call the init method
                localize.initLocalizedResources();
                // set the flag to keep from looping in init
                localize.resourceFileLoaded = true;
                // return the empty string
                return result;
            }
            // make sure the dictionary has valid data
            if ((localize.dictionary !== []) &#038;&#038; (localize.dictionary.length > 0)) {
                // use the filter service to only return those entries which match the value
                // and only take the first result
                var entry = $filter('filter')(localize.dictionary, {key:value})[0];
                // check to make sure we have a valid entry
                if ((entry !== null) &#038;&#038; (entry != undefined)) {
                    // set the result
                    result = entry.value;
                }
            }
            // return the value to the call
            return result;
        }
    };
    // return the local instance when called
    return localize;
} ]).
    filter('i18n', ['localize', function (localize) {
    return function (input) {
        return localize.getLocalizedString(input);
    };
}]);
</pre>
<h2>A Sample App</h2>
<p>So now we have a service and a filter, but we need to show how to use both in an app. So included in the project on GitHub is a sample app that uses the service and filter to populate all of the text displayed in both the index.html and two partials.</p>
<p>First we need to add a dependency to our app so, it will load our service and filter at bootstrap time. so we are going to add the name of the module, &#8216;localization&#8217;, into the app&#8217;s dependency list as shown in the code below:</p>
<pre class="dontquote prettyprint lang-js linenumstrigger linenums">
angular.module('localizeApp', ['localization']).
    config(['$routeProvider', function ($routeProvider) {
    $routeProvider.
        when('/', {templateUrl:'partials/home.html', controller:HomeController}).
        when('/edit/:index', {templateUrl:'partials/form.html', controller:EditPersonController}).
        when('/new', {templateUrl:'partials/form.html', controller:NewPersonController}).
        otherwise({redirectTo:'/'});
}]);
</pre>
<p>Now when ever we need to pull a localized string, we can use the filter. There are two ways you can call the filter, inside of a ng-bind method and by enclosing it inside of {{ }}. Below is a example of how to use each:</p>
<pre class="dontquote prettyprint lang-html linenumstrigger linenums">
&lt;div class="container-fluid" &gt;
    &lt;div class="row-fluid"&gt;
        &lt;h2 ng-bind="'_FormControllerTitle_' | i18n"&gt;&lt;/h2&gt;
    &lt;/div&gt;
    &lt;div class="row-fluid"&gt;
        &lt;form name="myForm" class="form-horizontal span5 well"&gt;
            &lt;div class="row-fluid"&gt;
                &lt;input type="text" ng-model="person.FirstName" required id="FirstName" name="FirstName" class="input-large" placeholder="{{'_FirstNameLabel_' | i18n}}" /&gt;
            &lt;/div&gt;
            &lt;div class="row-fluid"&gt;
                &nbsp;
            &lt;/div&gt;
            &lt;div class="row-fluid"&gt;
                &lt;input type="text" ng-model="person.LastName" required id="LastName" name="LastName" class="input-large" placeholder="{{'_LastNameLabel_' | i18n}}"/&gt;
            &lt;/div&gt;
            &lt;div class="row-fluid"&gt;
                &nbsp;
            &lt;/div&gt;
            &lt;div class="row-fluid"&gt;
                &lt;input type="text" ng-model="person.Email" required id="Email" name="Email" class="input-large" placeholder="{{'_EMailLabel_' | i18n}}"/&gt;
            &lt;/div&gt;
            &lt;div class="row-fluid"&gt;
                &nbsp;
            &lt;/div&gt;
            &lt;div class="row-fluid"&gt;
                &lt;textarea ng-model="person.Bio" required id="Bio" name="Bio" class="input-xxlarge" placeholder="{{'_BioLabel_' | i18n}}"&gt;&lt;/textarea&gt;
            &lt;/div&gt;
            &lt;div class="row-fluid"&gt;
                &nbsp;
            &lt;/div&gt;
            &lt;div class="row-fluid"&gt;
                &lt;button class="btn-primary" ng-click="savePerson()" ng-bind="'_SaveButtonLabel_' | i18n"&gt;&lt;/button&gt;
                &lt;button class="btn-primary" ng-click="cancel()" ng-bind="'_CancelButtonLabel_' | i18n"&gt;&lt;/button&gt;
            &lt;/div&gt;
        &lt;/form&gt;
    &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>Remember, you must use the {{ }} notation when you are not passing the value to a angular directive, if you don&#8217;t then the compiler will not handle the expression correctly and you&#8217;ll end up with text like &#8216;_BioLabel_&#8217; | i18n all over your web page.</p>
<p>Below are two examples of the filter in use, the first is using the default of U.S. English and the second is when you change Chrome&#8217;s language to display Spanish. Since I don&#8217;t speak Spanish, I&#8217;ve converted the resource strings into Pig Latin so you can see the difference.</p>
<p><a href="http://codingsmackdown.tv/blog/2012/12/14/localizing-your-angularjs-app/example_1/" rel="attachment wp-att-105"><img src="http://codingsmackdown.tv/wp-content/uploads/2012/12/Example_1.png" alt="Example_1" width="411" height="716" class="alignnone size-full wp-image-105" /></a> <a href="http://codingsmackdown.tv/blog/2012/12/14/localizing-your-angularjs-app/example_2/" rel="attachment wp-att-106"><img src="http://codingsmackdown.tv/wp-content/uploads/2012/12/Example_2.png" alt="Example_2" width="411" height="721" class="alignnone size-full wp-image-106" /></a></p>
<h2>The Wrap Up</h2>
<p>So in this article, I covered how to build a simple service and filter that can be used to localize you application based on the user&#8217;s language settings. By using a filter to front-end the service you have separated the concerns and provided a cross cutting service that can be used by your app without any of the controllers needing to deal with the service.</p>
<p>I also covered the basics of defining a service and a filter, injecting dependencies into both the service and filter, as well as how to use a filter in your HTML markup and directives.</p>
<p>Although this service handles a good share of the localization challenge for you a more advanced version would take advantage of Angular&#8217;s ng-pluralize directive and $locale service to help handle the harder semantics of language pluralization and gender. Hopefully it will get you started on the way to localizing you AngularJS apps and by following tutorial you&#8217;ve learned a little bit more about AngularJS.</p>
<p>Complete source for this tutorial can be found on GitHub at <a href="https://github.com/lavinjj/angularjs-localizationservice" title="angularjs-localizationservice">https://github.com/lavinjj/angularjs-localizationservice</a></p>
<p>I hope this tutorial helps you get started writing AngularJS Services and Filters. Drop me a comment on other AngularJS topics you’d like to see more tutorials on.</p>
]]></content:encoded>
			<wfw:commentRss>http://codingsmackdown.tv/blog/2012/12/14/localizing-your-angularjs-app/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Creating a Simple AngularJS Directive</title>
		<link>http://codingsmackdown.tv/blog/2012/12/14/creating-a-simple-angularjs-directive/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=creating-a-simple-angularjs-directive</link>
		<comments>http://codingsmackdown.tv/blog/2012/12/14/creating-a-simple-angularjs-directive/#comments</comments>
		<pubDate>Fri, 14 Dec 2012 07:06:03 +0000</pubDate>
		<dc:creator>Jim Lavin</dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[code.explode]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Directive]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Programing]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://codingsmackdown.tv/?p=84</guid>
		<description><![CDATA[One of the core features of AngularJS is the ability to extend the HTML Syntax with directives. Directives allow you to componentize segments of HTML into a single tag that can be re-used throughout your AngularJS app. So instead of repeating the following HTML all over your code: &#60;div class="row-fluid" ng-repeat="adjunct in adjuncts &#124; filter:search [...]]]></description>
				<content:encoded><![CDATA[<p>One of the core features of AngularJS is the ability to extend the HTML Syntax with directives. Directives allow you to componentize segments of HTML into a single tag that can be re-used throughout your AngularJS app. So instead of repeating the following HTML all over your code:</p>
<pre class="dontquote prettyprint lang-html">
    &lt;div class="row-fluid" ng-repeat="adjunct in adjuncts | filter:search | orderBy:'name'"&gt;
        &lt;div class="span1"&gt;{{adjunct.Name}}&lt;/div&gt;
        &lt;div class="span1"&gt;{{adjunct.Type}}&lt;/div&gt;
        &lt;div class="span1"&gt;{{adjunct.Use}}&lt;/div&gt;
        &lt;div class="span1"&gt;{{adjunct.Time}}&lt;/div&gt;
        &lt;div class="span1"&gt;{{adjunct.Amount}}&lt;/div&gt;
        &lt;div class="span1"&gt;{{adjunct.UseFor}}&lt;/div&gt;
        &lt;div class="span1"&gt;{{adjunct.Notes}}&lt;/div&gt;
        &lt;div&gt;&lt;a href="#/editadjunct/{{adjunct._id.$oid}}"&gt;&lt;i class="icon-pencil"&gt;&lt;/i&gt;&lt;/a&gt;&lt;/div&gt;
    &lt;/div&gt;
</pre>
<p>With a directive you can use the following HTML:</p>
<pre class="dontquote prettyprint lang-html">
    &lt;div data-display-adjunct class="row-fluid" ng-repeat="adjunct in adjuncts | filter:search | orderBy:'name'"&gt;
</pre>
<p>Now anywhere where you would use the above HTML, you can use the directive instead and be consistent across you entire site. This also saves you time when changes are required. If the amount of data that needs to be displayed changes you only need to update the directive and your done. You don’t have to hunt around your HTML files looking for every occurrence to change.</p>
<p>Directives allow you to not only specify what data from your app to bind to, but they can also handle the work of transforming the data into different formats, removing that responsibility from your controller, helping you to keep to the single responsibility principle.</p>
<p>If you apply this simple principle on bigger scales, directives can be used to build rich components that bind to your app’s data and reduce the amount of HTML you need to create across your entire site.</p>
<p>In this article,&nbsp;I’m going to show you how to write a simple directive that generates an image tag with a user’s avatar from the Gravatar site, <a title="http://en.gravatar.com/" href="http://en.gravatar.com/">http://en.gravatar.com/</a></p>
<p><span id="more-84"></span></p>
<h2>The Gravatar Image Directive Overview</h2>
<p>Gravatar allows you to upload an image and link it to your email address, so it can be used by the various social networking and forum sites on the web.</p>
<p>If you head over to the Gravatar developer documentation on how to request images, <a title="http://en.gravatar.com/site/implement/images/" href="http://en.gravatar.com/site/implement/images/">http://en.gravatar.com/site/implement/images/</a>. You’ll see that you need to create a md5 hash of the user’s email and then append that to a Url along with parameters for size, rating, and default image.</p>
<p>So the Url for my email address jlavin@jimlavin.net gets converted into the following image tag:</p>
<pre class="dontquote prettyprint lang-html">
    &lt;img src="http://www.gravatar.com/avatar/80b03752791145a3fdd027b154d7b42b?s=40&amp;r=pg&amp;d=404"&gt;
</pre>
<p>So we are going to write a directive that will take an email address and inject the resulting image tag into the page. When we are complete the directive will look something like this:</p>
<pre class="dontquote prettyprint lang-html">
    &lt;gravatar-image data-email="currentBrewer.Email" data-size="40" &gt;&lt;/gravatar-image&gt;
</pre>
<h2>Defining the Directive</h2>
<p>To start out we’ll need to create a new JavaScript file and call it gravatardirective.js and we’ll&nbsp;start with the basic skeleton for a directive.</p>
<pre class="dontquote prettyprint lang-js">
1: 'use strict';
2:
3: /*
4: * An Simple AngularJS Gravatar Directive
5: *
6: * Written by Jim Lavin
7: * http://codingsmackdown.tv
8: *
9: */
10:
11: angular.module('ui-gravatar', []).
12:     directive('gravatarImage', function () {
13:         return {
14:             restrict:"EAC",
15:             link:function (scope, elm, attrs) {
16:         }};
17:     });
</pre>
<p>So to define a directive we need to create an Angular module, provide a namespace, ‘ui-gravatar&#8217;, and include any dependencies the directive might require. In our case there are no dependencies so we can send in an empty array as seen on line 11.</p>
<p>Next we are going to use chaining to declare our directive by appending .directive after the module declaration.</p>
<p>In Angular, you can call your directive in several different ways. You can call it by using an element, an attribute, a class or as a comment. The following are all valid ways to call a directive:</p>
<pre class="dontquote prettyprint lang-html">
    &lt;gravatar-image data-email="email&gt;&lt;/gravatar-image&gt;
    &lt;div gravatar-image="email"&gt;&lt;/div&gt;
    &lt;div class="gravatar-image: email"&gt;&lt;/div&gt;
</pre>
<p>Angular will then replace the dash and convert the name into Camel case format, so we need to ensure we name our directive using Camel case, gravatarImage. so while Angular is parsing the DOM it can find our directive. You can see this on line 12 of the code above.</p>
<p>Next we provide a function that will return a Directive Definition Object that tells Angular about our directive. You can see the declaration starting on line 12 continuing through to line 17.</p>
<p>By default Angular will restrict calling directives to attributes only. To change this you can declare a restrict property and return the ways you want the directive to be called. I do this on line 14 by returning “EAC”, which means you should be able to call directive using an element, attribute or class.</p>
<p>Next, we are going to declare a link function that will be used to update the DOM as the data we are binding to changes. You can see the declaration on line 15.</p>
<p>The link function can take up to 4 parameters; the scope to be used by the directive, the instance element the directive will be modifying, the element attributes and an optional controller instance if a directive on the element has defined one.</p>
<h2>Simple Data Binding</h2>
<p>So we are going to need an email address in order to formulate the Url to retrieve an avatar image. To do this we can use simple data binding and send the data value or object we want to bind to as part of the directive’s declaration as shown below:</p>
<pre class="dontquote prettyprint lang-html">
    &lt;div gravatar-image="email" &gt;&lt;/div&gt;
</pre>
<p>To access the data, we’ll need to use the attributes instance to setup a watch on the data and then as we are notified of changes, we can update the DOM accordingly. The reason we have to setup a watch is because initially the data will come through as undefined as Angular compiles the DOM, only when it runs the linker to bind the data to the DOM will a value be present in our scope.</p>
<p>To do this we will need to modify our directive to add a watch function which will be called each time the value is updated.</p>
<pre class="dontquote prettyprint lang-js">
1: 'use strict';
2:
3: /*
4: * An Simple AngularJS Gravatar Directive
5: *
6: * Written by Jim Lavin
7: * http://codingsmackdown.tv
8: *
9: */
10:
11: angular.module('ui-gravatar', []).
12:     directive('gravatarImage', function () {
13:         return {
14:             restrict:"EAC",
15:             link:function (scope, elm, attrs) {
16:                 // by default the values will come in as undefined so we need to setup a
17:                 // watch to notify us when the value changes
18:                 scope.$watch(attrs.gravatarImage, function (value) {
19:                     elm.text(value);
20:             });
21:         }};
22:     });
</pre>
<p>Starting on line 18 we declare the watch function and each time the data updates, we set the element’s text to the updated value.</p>
<p>One thing to notice is we are supplying the value supplied in the attributes instance to the watch, not the scope value, since the scope value is undefined when the link function is called and the watch will never be triggered.</p>
<p>To finish our first version of the directive let’s create the Url and append an image tag to the element so it will retrieve the Gravatar image.</p>
<pre class="dontquote prettyprint lang-js">
1: 'use strict';
2:
3: /*
4: * An Simple AngularJS Gravatar Directive
5: *
6: * Written by Jim Lavin
7: * http://codingsmackdown.tv
8: *
9: */
10:
11: angular.module('ui-gravatar', []).
12:     directive('gravatarImage', function () {
13:         return {
14:             restrict:"EAC",
15:             link:function (scope, elm, attrs) {
16:                 // by default the values will come in as undefined so we need to setup a
17:                 // watch to notify us when the value changes
18:                 scope.$watch(attrs.gravatarImage, function (value) {
19:                     // let's do nothing if the value comes in empty, null or undefined
20:                     if ((value !== null) &amp;&amp; (value !== undefined) &amp;&amp; (value !== '')) {
21:                         // convert the value to lower case and then to a md5 hash
22:                         var hash = md5(value.toLowerCase());
23:                         // construct the tag to insert into the element
24:                         var tag = '&lt;img alt="" src="http://www.gravatar.com/avatar/' + hash + '?s=40&amp;r=pg&amp;d=404" /&gt;'
25:                         // insert the tag into the element
26:                         elm.append(tag);
27:                     }
28:             });
29:         }};
30:     });
</pre>
<p>Now, when the watch function is called, I evaluate the value and if it is not empty, null or undefined, I force it to lower case, create a md5 hash of the email, format the image tag and append it to the element. Which gives us the following result when we use it an app.</p>
<p><img style="background-image: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="SampleWebPage_1" alt="SampleWebPage_1" src="http://codingsmackdown.tv/wp-content/uploads/2012/12/SampleWebPage_1_thumb.png" width="501" height="484" border="0" /></p>
<h2>Adding Configuration Attributes</h2>
<p>Now, our directive works great but what if you want to use different sizes of the avatar at different places in your app or maybe you want to only allow PG rated avatars since you have people of all ages using your app and you don’t want to offend anyone.</p>
<p>We could create various version of the directive and name them gravatar-image-small or gravatar-image-pg, but that won’t do. We need to provide those values when we call the directive.</p>
<p>To do this we’ll need to send additional configuration elements to the directive so we can dynamically tell Gravatar what we need.</p>
<p>So, let’s change our directive to look for specific attributes on the element so we can specify the size, rating and default avatar.</p>
<p>We are going to look for three attributes in our directive; size, rating and default. Now we can do this many ways but the simplest is to use data-xxx attributes in the element and then we can read the values using attrs.xxx. This is because Angular will strip off “data-“ from any attributes as is creates the attributes instance, which make it easy for us.</p>
<p>so now when we call our directive we can use the following HTML:</p>
<pre class="dontquote prettyprint lang-html">
    &lt;div gravatar-image data-email="email" data-size="120" data-rating="pg" data-default="404" &gt;&lt;/div&gt;
</pre>
<p>The code for directive now includes the logic to parse the attributes use their values or supply defaults if they are missing. I’ve also moved the data we are binding to it’s own attribute data-email, which will make things easier if we decide to use the directive as an element.</p>
<p>Below is the new directive, coded to retrieve the attributes and format the Url accordingly:</p>
<pre class="dontquote prettyprint lang-js">
1: 'use strict';
2:
3: /*
4: * An Simple AngularJS Gravatar Directive
5: *
6: * Written by Jim Lavin
7: * http://codingsmackdown.tv
8: *
9: */
10:
11: angular.module('ui-gravatar', []).
12:     directive('gravatarImage', function () {
13:         return {
14:             restrict:"EAC",
15:             link:function (scope, elm, attrs) {
16:                 // by default the values will come in as undefined so we need to setup a
17:                 // watch to notify us when the value changes
18:                 scope.$watch(attrs.email, function (value) {
19:                     // let's do nothing if the value comes in empty, null or undefined
20:                     if ((value !== null) &amp;&amp; (value !== undefined) &amp;&amp; (value !== '')) {
21:                         // convert the value to lower case and then to a md5 hash
22:                         var hash = md5(value.toLowerCase());
23:                         // parse the size attribute
24:                         var size = attrs.size;
25:                         // default to 40 pixels if not set
26:                         if((size=== null) || (size == undefined) || (size == '')){
27:                             size = 40;
28:                         }
29:                         // parse the ratings attribute
30:                         var rating = attrs.rating;
31:                         // default to pg if not set
32:                         if((rating === null) || (rating === undefined)|| (rating === '')){
33:                             rating = 'pg';
34:                         }
35:                         // parse the default image url
36:                         var defaultUrl = attrs.default;
37:                         if((defaultUrl === null) || (defaultUrl === undefined)|| (defaultUrl === '')) {
38:                             defaultUrl = '404';
39:                         }
40:                         // construct the tag to insert into the element
41:                         var tag = '&lt;img alt="" src="http://www.gravatar.com/avatar/' + hash + '?s=' + size + '&amp;r=' + rating + '&amp;d=' + defaultUrl + '" /&gt;'
42:                         // insert the tag into the element
43:                         elm.append(tag);
44:                     }
45:                 });
46:             }};
47:         });
</pre>
<p>Now, starting at line 24 we parse the size attribute and if it has a value we use it, otherwise we use a default value.</p>
<p>We do the same thing for the rating and default attributes starting on lines 30 and 36.</p>
<p>Line 41 now reflects the tag with all of the various configurations supplied. You might also notice in our watch statement that we changed the watch value from attrs.gravatarImage to attrs.email since we are now passing the data binding value in using the data-email attribute.</p>
<h2>Wrap Up</h2>
<p>Writing directives in AngularJS can be hard, but by starting out simple, you will learn how things work in AngularJS and as you experiment more you will be able to build very complex components that can extend HTML, which will save you time and decrease the amount of HTML your team needs to write.</p>
<p>The source code for this article, along with a sample app can be found on Github at <a title="https://github.com/lavinjj/angularjs-gravatardirective" href="https://github.com/lavinjj/angularjs-gravatardirective">https://github.com/lavinjj/angularjs-gravatardirective</a></p>
<p>I hope this tutorial helps you get started writing AngularJS Directives. Drop me a comment on other AngularJS topics you&#8217;d like to see more tutorials on.</p>
]]></content:encoded>
			<wfw:commentRss>http://codingsmackdown.tv/blog/2012/12/14/creating-a-simple-angularjs-directive/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.697 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2013-06-08 21:51:33 -->
