<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Pseudobry</title>
    <description>Husband. Father. Software Engineer. Open Source Hacker. Always Learning.
</description>
    <link>http://www.pseudobry.com/</link>
    <atom:link href="http://www.pseudobry.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sun, 17 Jul 2016 22:09:44 +0000</pubDate>
    <lastBuildDate>Sun, 17 Jul 2016 22:09:44 +0000</lastBuildDate>
    <generator>Jekyll v3.1.6</generator>
    
      <item>
        <title>Introduction to Data Modeling with JSData</title>
        <description>&lt;p&gt;Inspired by &lt;a href=&quot;https://github.com/emberjs/data&quot;&gt;Ember Data&lt;/a&gt;, &lt;a href=&quot;http://www.js-data.io&quot;&gt;&lt;strong&gt;JSData&lt;/strong&gt;&lt;/a&gt; is a framework-agnostic, datastore-agnostic ORM for Node.js and the Browser.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.js-data.io/docs/working-with-adapters&quot;&gt;JSData’s adapters&lt;/a&gt; handle communication with various storage layers, such as &lt;code class=&quot;highlighter-rouge&quot;&gt;localStorage&lt;/code&gt;, Firebase, RethinkDB, or your RESTful backend.&lt;/p&gt;

&lt;p&gt;In a typical scenario, you load data into the store, which maintains a single representation of every unique record coming from your storage layer. The data store offers an API for read, update, and delete operations, which are executed in your storage layer by an adapter, with the results finally synced back to the store. This is your &lt;em&gt;Data&lt;/em&gt; or &lt;em&gt;Model layer&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The Model layer is typically where your business logic resides–where you manipulate your data. There are many variations on this pattern, and JSData can work with your preferences.&lt;/p&gt;

&lt;p&gt;JSData runs in the browser, communicating with storage layers such as &lt;code class=&quot;highlighter-rouge&quot;&gt;localStorage&lt;/code&gt;, Firebase, your RESTful backend (HTTP target), etc.&lt;/p&gt;

&lt;p&gt;JSData also runs in NodeJS, where adapters for MongoDB, Redis, RethinkDB, MySql/Postgres/SQLite, etc. are available.&lt;/p&gt;

&lt;p&gt;JSData presents a uniform API for executing your typical &lt;a href=&quot;https://en.wikipedia.org/wiki/Create,_read,_update_and_delete&quot;&gt;CRUD&lt;/a&gt; operations against any storage layer for which an adapter is available. You can easily combine adapters for more complicated data management.&lt;/p&gt;

&lt;p&gt;It is easy to add JSData to your project. Let’s get started:&lt;/p&gt;

&lt;h4 id=&quot;install&quot;&gt;Install&lt;/h4&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;npm|bower&amp;gt; install --save js-data
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;JSData is available on &lt;a href=&quot;https://cdnjs.com/libraries/js-data&quot;&gt;cdnjs&lt;/a&gt; and &lt;a href=&quot;http://www.jsdelivr.com/#!js-data&quot;&gt;jsDelivr&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can add JSData to your app as a script tag, via &lt;code class=&quot;highlighter-rouge&quot;&gt;import JSData from &#39;js-data&#39;&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;require(&#39;js-data&#39;)&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;define([&#39;js-data&#39;], ...)&lt;/code&gt;, etc.&lt;/p&gt;

&lt;h4 id=&quot;create-a-store&quot;&gt;Create a store&lt;/h4&gt;

&lt;iframe style=&quot;width: 100%;&quot; src=&quot;http://embed.plnkr.co/H0XBoFdaGI4k6YOf3BW0/store.js&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;DS&lt;/code&gt; constructor function takes an optional &lt;code class=&quot;highlighter-rouge&quot;&gt;options&lt;/code&gt; object which can be used to override the default settings for your new store. You can also create a store via &lt;code class=&quot;highlighter-rouge&quot;&gt;JSData.createStore([options])&lt;/code&gt;.&lt;/p&gt;

&lt;h4 id=&quot;connect-to-storage&quot;&gt;Connect to storage&lt;/h4&gt;

&lt;p&gt;We’re not actually working with any storage layers yet, so let’s register an adapter.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;npm|bower&amp;gt; install --save js-data-firebase
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;js-data-firebase is available on &lt;a href=&quot;https://cdnjs.com/libraries/js-data-firebase&quot;&gt;cdnjs&lt;/a&gt; and &lt;a href=&quot;http://www.jsdelivr.com/#!js-data-firebase&quot;&gt;jsDelivr&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can add js-data-firebase to your app as a script tag, via &lt;code class=&quot;highlighter-rouge&quot;&gt;import DSFirebaseAdapter from &#39;js-data-firebase&#39;&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;require(&#39;js-data-firebase&#39;)&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;define([&#39;js-data&#39;, &#39;js-data-firebase&#39;], ...)&lt;/code&gt;, etc.&lt;/p&gt;

&lt;iframe style=&quot;width: 100%; height: 235px;&quot; src=&quot;http://embed.plnkr.co/H0XBoFdaGI4k6YOf3BW0/register-firebase.js&quot;&gt;&lt;/iframe&gt;

&lt;h4 id=&quot;model-your-data&quot;&gt;Model your data&lt;/h4&gt;

&lt;p&gt;You start modeling your data by registering Resources with the store:&lt;/p&gt;

&lt;iframe style=&quot;width: 100%;&quot; src=&quot;http://embed.plnkr.co/H0XBoFdaGI4k6YOf3BW0/User.js&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;A &lt;a href=&quot;http://www.js-data.io/docs/resources&quot;&gt;JSData Resource&lt;/a&gt; defines metadata that the store uses to interact with data of that type. The Resource object returned by &lt;code class=&quot;highlighter-rouge&quot;&gt;DS#defineResource(options)&lt;/code&gt; exposes an API for working directly with data of that Resource.&lt;/p&gt;

&lt;p&gt;With a few lines of code, we can already do all kinds of things with data of type &lt;code class=&quot;highlighter-rouge&quot;&gt;User&lt;/code&gt;.&lt;/p&gt;

&lt;iframe style=&quot;width: 100%;height:330px&quot; src=&quot;http://embed.plnkr.co/H0XBoFdaGI4k6YOf3BW0/inject-user.js&quot;&gt;&lt;/iframe&gt;

&lt;h4 id=&quot;create-a-user-in-firebase&quot;&gt;Create a user in Firebase&lt;/h4&gt;

&lt;iframe style=&quot;width: 100%;height:350px&quot; src=&quot;http://embed.plnkr.co/H0XBoFdaGI4k6YOf3BW0/create.js&quot;&gt;&lt;/iframe&gt;

&lt;h4 id=&quot;update-the-user&quot;&gt;Update the user&lt;/h4&gt;

&lt;iframe style=&quot;width: 100%;height:540px&quot; src=&quot;http://embed.plnkr.co/H0XBoFdaGI4k6YOf3BW0/update.js&quot;&gt;&lt;/iframe&gt;

&lt;h4 id=&quot;destroy-the-user&quot;&gt;Destroy the user&lt;/h4&gt;

&lt;iframe style=&quot;width: 100%;height:390px&quot; src=&quot;http://embed.plnkr.co/H0XBoFdaGI4k6YOf3BW0/destroy.js&quot;&gt;&lt;/iframe&gt;

&lt;h4 id=&quot;the-tip-of-the-iceberg&quot;&gt;The tip of the iceberg&lt;/h4&gt;

&lt;p&gt;I hardly had to write an code, and I already have a fully functional CRUD API on top of Firebase! I can easily add more resources, setup relations between them, and even add another adapter for a more complex application.&lt;/p&gt;

&lt;p&gt;You know when you show a treat to a starving (but obedient) puppy, and the puppy just starts drooling all over the floor? That puppy is you right now.&lt;/p&gt;

&lt;p&gt;JSData will save you time. It’s the Twitter Bootstrap of data layers.&lt;/p&gt;

&lt;p&gt;Knock yourself out:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/js-data&quot;&gt;JSData on Github&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://gitter.im/js-data/js-data&quot;&gt;Gitter Channel&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://groups.io/org/groupsio/jsdata&quot;&gt;Mailing List&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.js-data.io/&quot;&gt;JSData website&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=8wxnnJA9FKw&quot;&gt;MtnWestJS 2015 Presentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.js-data.io/docs/resources&quot;&gt;Resources/Models&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.js-data.io/docs/working-with-the-data-store&quot;&gt;Working with the Data Store&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.js-data.io/docs/working-with-adapters&quot;&gt;Adapters&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.js-data.io/docs/model-lifecycle&quot;&gt;Model Lifecycle&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.js-data.io/docs/custom-instance-behavior&quot;&gt;Custom Instance Behavior&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.js-data.io/docs/computed-properties&quot;&gt;Computed Properties&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.js-data.io/docs/query-syntax&quot;&gt;Query Syntax&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.js-data.io/docs/relations&quot;&gt;Relations&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.js-data.io/docs/jsdata-on-the-server&quot;&gt;JSData on the Server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 16 Jun 2015 00:00:00 +0000</pubDate>
        <link>http://www.pseudobry.com/introduction-to-data-modeling-with-jsdata/</link>
        <guid isPermaLink="true">http://www.pseudobry.com/introduction-to-data-modeling-with-jsdata/</guid>
        
        <category>technology,</category>
        
        <category>javascript</category>
        
        
      </item>
    
      <item>
        <title>Respect your data - An introduction to angular-data</title>
        <description>&lt;p&gt;A presentation of mine given at an AngularJS Utah meetup.&lt;/p&gt;

&lt;div&gt;
&lt;iframe src=&quot;http://slides.com/jdobry/angularjs-respect-your-data/embed&quot; width=&quot;650&quot; height=&quot;500&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; webkitallowfullscreen=&quot;webkitallowfullscreen&quot; mozallowfullscreen=&quot;mozallowfullscreen&quot; allowfullscreen=&quot;allowfullscreen&quot;&gt;
&lt;/iframe&gt;
&lt;/div&gt;
</description>
        <pubDate>Tue, 13 May 2014 00:00:00 +0000</pubDate>
        <link>http://www.pseudobry.com/respect-your-data-an-introduction-to-angular-data/</link>
        <guid isPermaLink="true">http://www.pseudobry.com/respect-your-data-an-introduction-to-angular-data/</guid>
        
        <category>technology,</category>
        
        <category>javascript</category>
        
        
      </item>
    
      <item>
        <title>Data Management &amp; Caching with Angular.js</title>
        <description>&lt;p&gt;A presentation of mine given at an AngularJS Utah meetup.&lt;/p&gt;

&lt;div&gt;
&lt;iframe src=&quot;http://slides.com/jdobry/data-management-caching-with-angular-js/embed&quot; width=&quot;650&quot; height=&quot;500&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; webkitallowfullscreen=&quot;webkitallowfullscreen&quot; mozallowfullscreen=&quot;mozallowfullscreen&quot; allowfullscreen=&quot;allowfullscreen&quot;&gt;
&lt;/iframe&gt;
&lt;/div&gt;
</description>
        <pubDate>Tue, 12 Nov 2013 00:00:00 +0000</pubDate>
        <link>http://www.pseudobry.com/data-management-caching-with-angular-js/</link>
        <guid isPermaLink="true">http://www.pseudobry.com/data-management-caching-with-angular-js/</guid>
        
        <category>technology,</category>
        
        <category>reality</category>
        
        
      </item>
    
      <item>
        <title>Let express.js and async.js make your life easier</title>
        <description>&lt;p&gt;Out of the box node.js provides an http module for sending and receiving HTTP
requests. It attempts to abstract away the more tedious parts of forming
requests and parsing responses. With the http module you can write scripts that
communicate with the world via HTTP or even write simple HTTP web servers. This
is great, but when it comes time to build a service api, node’s http module
starts to feel like a single screwdriver when you need an entire toolbox.
&lt;a href=&quot;http://expressjs.com/&quot;&gt;ExpressJS&lt;/a&gt; comes into the picture as a minimal and
flexible web application framework for node.js. Express provides a set of tools
for easily interacting with HTTP requests and responses, in addition to bringing
middleware layers to your api. In addition to the fundamental features provided
by Express, the highly popular &lt;a href=&quot;https://github.com/caolan/async&quot;&gt;async&lt;/a&gt; utility
provides a robust tool for managing asynchronous control flow. Consider this
RESTful api endpoint created using Express:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;/posts/:id&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// Pass the error on to be handled by some other middleware&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Here, syntactic sugar lays out an endpoint that accepts GET requests. Express
automatically parses parameters within the request url, and exposes them in the
params object of the request.&lt;/p&gt;

&lt;p&gt;Notice the line:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This is where the code checks for any errors returned by the database call.
Instead of handling the error on the spot with something like:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Handle the error on the spot&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;There was an error!&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;I pass the error down the middleware chain to be handled elsewhere. Requests
pass through middleware in the order that you tell Express to “use” them (see
code below). This is convenient when you want to handle errors from many places
with the same code. In order for this to work, previously in my application I
had told Express to add a handler to the middleware chain with something like
this:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// This tells express to route ALL requests through this middleware&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// This middleware ends up being a &quot;catch all&quot; error handler&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;500 - Internal Server Error&#39;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So when the request (GET “/posts/13”) comes from the client to Express, the
request is passed down the middleware chain until it is handled. Most middleware
don’t fully handle the request, but augment it. For example, Expresses uses
middleware to parse the url parameters and attach the params object to the
request object, which is then passed along to be handled by the code written to
handle the “/posts/:id” route. If there’s an error, the route can handle the
error, or pass it along to be handled by a middleware error handler like the one
above.&lt;/p&gt;

&lt;p&gt;Middleware is also especially useful for requiring authentication in api
endpoints. For example, we will secure the “/posts/:id” route:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;restrict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// User has active authenticated session, move along&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Unauthenticated!&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;401&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And now to tell Express to send the request through the “restrict” middleware
before letting the code for the “/posts/:id” route handle the request:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;/posts/:id&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;restrict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Using middleware, it’s possible to build a robust and highly functional service
api without duplicating code.&lt;/p&gt;

&lt;p&gt;When handling a request, and especially when that involves doing file I/O or
talking to a database, it often leads what’s called “callback hell”, or deeply
nested callback functions. This makes the code hard to read, as it’s hard to
follow the flow of the program. Here’s an example of trying to create a new
user:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;attrs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;user&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;attrs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;cb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;Email already exists!&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;user&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;attrs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;cb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;Username already exists!&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;user&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;attrs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newUser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;cb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
              &lt;span class=&quot;nx&quot;&gt;cb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newUser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Imagine how painful it would be to read code nested eight or ten levels deep!
Thankfully, async can help us out. Here’s the same example using async:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;attrs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;waterfall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// check for duplicate email&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;user&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;attrs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// check for duplicate username&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;cb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;Email already exists!&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;user&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;attrs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;username&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Insert the new user&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;cb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;Username already exists!&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;user&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;attrs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;return_vals&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now each step is listed in its logical order, at the same level of nesting. This
particular function of async–waterfall–performs asynchronous operations one
after another, each waiting for the previous to complete before executing, and
each receiving the return arguments of the preceding function. Async
automatically checks for errors and returns them, eliminating the &lt;code class=&quot;highlighter-rouge&quot;&gt;if (err) cb(err);&lt;/code&gt;
boilerplate code.&lt;/p&gt;

&lt;p&gt;Using the combination of Express and async on one of my projects has been a
pleasant exercise that’s resulted in a clear, concise api definition and easy to
follow code. I would definitely give async a try, as it can do &lt;em&gt;almost&lt;/em&gt;
everything promises can do, without the performance overhead.
&lt;a href=&quot;https://github.com/caolan/async&quot;&gt;async&lt;/a&gt; has a myriad of functions you can check
out.&lt;/p&gt;
</description>
        <pubDate>Fri, 04 Oct 2013 00:00:00 +0000</pubDate>
        <link>http://www.pseudobry.com/let-express-js-and-async-js-make-your-life-easier/</link>
        <guid isPermaLink="true">http://www.pseudobry.com/let-express-js-and-async-js-make-your-life-easier/</guid>
        
        <category>javascript,</category>
        
        <category>NodeJS,</category>
        
        <category>express.js,</category>
        
        <category>async.js</category>
        
        
      </item>
    
      <item>
        <title>What is Node.js?</title>
        <description>&lt;p&gt;This post is my basic answer to the question:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;What is NodeJS?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here I briefly discuss a few things about NodeJS that I think are essential to
understanding what NodeJS is as a programming language. This explanation is
neither totally comprehensive nor highly detailed.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;tldr;&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Node.js is an evented I/O framework for the V8 JavaScript engine. It is
intended for writing scalable network programs such as web servers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;long-version&quot;&gt;Long version:&lt;/h2&gt;

&lt;h4 id=&quot;event-driven-programming&quot;&gt;Event-driven programming&lt;/h4&gt;

&lt;p&gt;Event-driven programming is the idea that events control of the flow of a
program. When an event occurs, code registered to handle the event is executed.
When performing I/O, traditional programming is synchronous, meaning that an
executing thread must wait for the I/O operation to complete before it can
continue its execution. Solutions such as multi-threading were devised in order
to improve CPU productivity by switching between threads when a thread blocks.
Multi-threading does however introduce the overhead of switching between threads
and remembering each thread’s context.&lt;/p&gt;

&lt;p&gt;At the heart of NodeJS is an event loop that performs two tasks: Check to see if
an event has occurred and if so, execute the registered event handler. This
allows NodeJS to maintain a single thread that is constantly working, executing
event handlers as events occur.&lt;/p&gt;

&lt;h4 id=&quot;nodejs-is-javascript&quot;&gt;NodeJS is JavaScript&lt;/h4&gt;

&lt;p&gt;JavaScript–the most popular programming language in the world–is the language of
NodeJS. JavaScript has the concept of a closure: a function which remembers the
context in which is was declared, allowing it to access that same context when
it is executed later. This is perfect for event-driven programming. The
programmer can register functions as event handlers, and when the event finally
occurs these functions are then executed in the context in which the programmer
intended. Along with this come all the other features (and idiosyncrasies) of
JavaScript: basic data types, prototypal inheritance, loops, conditionals, etc.
There is no JavaScript Standard Library, but NodeJS does come with a core
library.&lt;/p&gt;

&lt;h4 id=&quot;buffers&quot;&gt;Buffers&lt;/h4&gt;

&lt;p&gt;NodeJS was originally written to handle text–specifically HTML. The Buffer class
was introduced to allow NodeJS to handle binary data. Buffers are chunks of
memory allocated outside of the JavaScript VM and are therefore immune to some
of the normal effects of garbage collection. Buffers can be sliced and copied.
The individual bytes of a Buffer can be manipulated. Buffers can be created from
Strings of various encodings, and can be converted into Strings of various
encodings. Buffers give NodeJS a range of capabilities that increase the
usefulness of NodeJS.&lt;/p&gt;

&lt;h4 id=&quot;nodejs-module-system&quot;&gt;NodeJS Module System&lt;/h4&gt;

&lt;p&gt;NodeJS does away with the global namespace and implements the CommonJS standard.
Files and modules have a one-to-one relationship. Each file chooses exactly what
will be publicly exposed by the file’s module when it is loaded by other
modules. NodeJS looks for core modules first, then modules with relative path
names, and finally looks in “./node_modules” when searching for modules. Each
module is cached the first time it is loaded, so the contents of each module are
only initialized once.&lt;/p&gt;

&lt;p&gt;The NodeJS core library provides the developer with a number of tools for
performing I/O, working with HTTP, files, the OS, streams, and much more. In
addition, &lt;a href=&quot;http://npmjs.org&quot;&gt;npmjs.org&lt;/a&gt; is a large repository of community and
open source packages for NodeJS. NodeJS is at home in small, rapidly developing
products, probably because NodeJS and its ecosystem are still (relatively) small
and under rapid development.&lt;/p&gt;

&lt;p&gt;Try it! It’s rediculously easy to get started and hard to drop once you get
going.&lt;/p&gt;
</description>
        <pubDate>Wed, 18 Sep 2013 00:00:00 +0000</pubDate>
        <link>http://www.pseudobry.com/what-is-node-js/</link>
        <guid isPermaLink="true">http://www.pseudobry.com/what-is-node-js/</guid>
        
        <category>javascript,</category>
        
        <category>NodeJS</category>
        
        
      </item>
    
      <item>
        <title>Building large apps with Angular.js</title>
        <description>&lt;p&gt;This post came out of my presentation at a UtahJS meetup. You can even go see my
&lt;a href=&quot;http://slid.es/jdobry/building-large-apps-with-angularjs&quot;&gt;slides&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;New to AngularJS? Confused by directive mumbo-jumbo? Giddy over Angular’s magic
and your new productivity? Jaded by gotchas you didn’t see coming? Enjoying the
zen of Angular?&lt;/p&gt;

&lt;div&gt;
&lt;iframe src=&quot;http://slid.es/jdobry/building-large-apps-with-angularjs/embed&quot; width=&quot;650&quot; height=&quot;500&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; webkitallowfullscreen=&quot;webkitallowfullscreen&quot; mozallowfullscreen=&quot;mozallowfullscreen&quot; allowfullscreen=&quot;allowfullscreen&quot;&gt;
&lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;Whatever your experience with Angular and whatever size of project you’re
working on, there will come a day when you encounter Angular in the wild being
used on a large project. Does that sound like a dream come true or are you still
wary? Either way, you will inevitably run into a problem that Angular does not
solve for you. Will you survive?&lt;/p&gt;

&lt;p&gt;If you’ve needed to:
- Organize your files
- Name your files
- Lazy-load your code
- Serialize application state to the URL
- Derive application state from the URL
- Manage a Model layer
- Do smart caching
- Work with a RESTful interface (for real)
- Use a 3rd-party lib with Angular&lt;/p&gt;

&lt;p&gt;Then you’ve already met the beast.&lt;/p&gt;

&lt;p&gt;Angular is not the framework to end all frameworks, however, never before have I
derived so much pleasure from web development. Not with NodeJs, not with NoSQL,
not with BackboneJS. To misquote &lt;a href=&quot;https://twitter.com/ryanflorence&quot;&gt;@ryanflorence&lt;/a&gt;: “I’m Sick of the Web: [Angular]’s Healing Balm”.&lt;/p&gt;

&lt;p&gt;My first few weeks with AngularJS I was like a kid on Christmas morning,
unwrapping presents as fast as I could and running around showing everybody.
Then my new race car broke after 10 loops around the track, I found that none of
my previous toys played nice with my new ones, and I realized I would need a
Ph.D. to understand my new book “Directives for Dummies”. After a few months of
hate/love, things started to click. Directives became my best friends, Angular
best practices got me up and running, and I began derive real satisfaction from
my work.&lt;/p&gt;

&lt;p&gt;Now before you think it’s all fun and games, here are some points to consider as
you embark on your journey building large apps with Angular:&lt;/p&gt;

&lt;h1 id=&quot;convention-vs-configuration&quot;&gt;Convention vs Configuration&lt;/h1&gt;

&lt;p&gt;When a framework embraces conventions, developers familiar with the framework
can move from project to project with minimal “ramp up” time in order to become
familiar with each project. It basically comes down to familiarizing oneself
with the project’s business domain. The purpose of conventions is to improve:&lt;/p&gt;

&lt;p&gt;“Conventionless” frameworks result in fragmentation, meaning that one
developer’s use of a framework can differ wildly from another’s. Example:
BackboneJS. An excellent tool in and of itself—but decidedly lacking in enforced
conventions. Have you ever seen two Backbone developers do something the exact
same way? They might look at each others’ project and have no idea what is going
on. Freedom has its downsides.&lt;/p&gt;

&lt;p&gt;In regard to convention, AngularJS is a little on the light side. AngularJS puts
itself forth as a “MVW” framework loosely based on a traditional MVC framework.
Angular Controllers setup and add behavior to &lt;code class=&quot;highlighter-rouge&quot;&gt;$scope&lt;/code&gt; objects, and Angular’s
templates and two-binding make for a nifty View layer, but Angular has virtually
no opinion when it comes to your Model layer. You can do whatever you want.&lt;/p&gt;

&lt;p&gt;The path to successfully building a large, fast, and stable application with
AngularJS lies in finding and following conventions for you and your dev team.
The AngularJS documentation doesn’t help much with that, but many developers are
becoming experienced with Angular and have shared the conventions that have
helped them find success. You can’t commit to writing your large application
with AngularJS without paying attention to the &lt;a href=&quot;https://groups.google.com/forum/#!forum/angular&quot;&gt;mailing list&lt;/a&gt;,
the &lt;a href=&quot;https://github.com/angular/angular.js&quot;&gt;GitHub project&lt;/a&gt;, and the opinions of
Angular’s core contributors.&lt;/p&gt;

&lt;h1 id=&quot;model-layer&quot;&gt;Model Layer&lt;/h1&gt;

&lt;p&gt;Large applications often have a lot of data to deal with, so designing a solid
Model layer is essential to building and maintaining a stable Angular
application. Angular Services provide a useful tool for separating your Model
layer or business logic from your View and Controller layers. &lt;code class=&quot;highlighter-rouge&quot;&gt;$rootScope&lt;/code&gt; and
&lt;code class=&quot;highlighter-rouge&quot;&gt;$scope&lt;/code&gt; are useful as the Model layer for small applications, but can quickly
become a mass of messy prototypal inheritance chains that may or may not work
the way you think they will. For example:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;$scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fruit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;banana&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$newScope&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;$new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;$scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fruit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// &#39;banana&#39;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$newScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fruit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// &#39;banana&#39;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;$newScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fruit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;apple&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$newScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fruit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// &#39;apple&#39;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;$scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fruit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// &#39;banana&#39; // Did you think it would be &#39;apple&#39;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;In a large AngularJS application it is important to have a source of truth for
your data. Keep your data in your Angular Services and use your Controllers to
expose your data to your views.&lt;/p&gt;

&lt;p&gt;Your services own your data:
```js
app.service(‘MyService’, function ($http, $q, $angularCacheFactory) {
    var _dataCache = $angularCacheFactory(‘dataCache’, {
        maxAge: 3600000 // items expire after an hour
    });
    /**
     * @class MyService
     */
    return {
        manipulateData: function (input) {
            var output;
            // do something with the data
            return output;
        },&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    getDataById: function (id) {
        var deferred = $q.defer();
        if (_dataCache.get(id)) {
            deferred.resolve(_dataCache.get(id));
        } else {
            // Get the data from the server and populate cache
        }
        return deferred.promise;
    }
}; }); ```
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Your controllers and directives consume your data:
&lt;code class=&quot;highlighter-rouge&quot;&gt;js
$scope.$watch(function () {
  return MyDataService.getMyData();
}, function () {
  $scope.myData = MyDataService.getMyData();
});
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ultimately, you’ll want your Model layer to support the needs of a large
client-side application. Many tools exist. The point is to not let Angular do
your Model layer for you, because you’ll be disappointed. Look into something
like &lt;a href=&quot;http://docs.angularjs.org/api/ngResource.$resource&quot;&gt;$resource&lt;/a&gt;,
&lt;a href=&quot;https://github.com/mgonto/restangular&quot;&gt;restangular&lt;/a&gt;, &lt;a href=&quot;http://www.breezejs.com/&quot;&gt;BreezeJS&lt;/a&gt;,
or even using BackboneJS Models/Collections. Treat your data with respect.&lt;/p&gt;

&lt;h1 id=&quot;file-organization&quot;&gt;File Organization&lt;/h1&gt;

&lt;p&gt;Found at the heart of many an argument is the issue of file organization and
naming. Where do we put everything? Do we organize by type, form, function, or
feature? PascalCase or camelCase? Some frameworks make this decision for you by
enforcing a convention. Ruby on Rails, for example, expects to find your
controllers in &lt;code class=&quot;highlighter-rouge&quot;&gt;myApp/app/controller/&lt;/code&gt; and your views in &lt;code class=&quot;highlighter-rouge&quot;&gt;myApp/app/views/&lt;/code&gt;.
This leaves little room for argument or ambiguity. Some frameworks also use
naming conventions to find your files. Here is an example taken from the
&lt;a href=&quot;http://emberjs.com/&quot;&gt;EmberJS&lt;/a&gt; website:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Router&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;about&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/about&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;favorites&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/favs&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;When the user visits &lt;code class=&quot;highlighter-rouge&quot;&gt;/&lt;/code&gt;, Ember.js will render the &lt;code class=&quot;highlighter-rouge&quot;&gt;index&lt;/code&gt; template. Visiting
&lt;code class=&quot;highlighter-rouge&quot;&gt;/about&lt;/code&gt; renders the &lt;code class=&quot;highlighter-rouge&quot;&gt;about&lt;/code&gt; template, and &lt;code class=&quot;highlighter-rouge&quot;&gt;/favs&lt;/code&gt; renders the &lt;code class=&quot;highlighter-rouge&quot;&gt;favorites&lt;/code&gt;
template. Note that you can leave off the path if it is the same as the route
name. In this case, the following is equivalent to the above example:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Router&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;about&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;favorites&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/favs&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The AngularJS framework itself does not provide any such conventions. It’s all
up to you. Below are some possible solutions.&lt;/p&gt;

&lt;h3 id=&quot;monolithic-files&quot;&gt;Monolithic files&lt;/h3&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/angular/angular-seed&quot;&gt;angular-seed&lt;/a&gt; project recommends
something like the following for project file organization:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;partials/
  home.html
  login.html
  users.html
  orders.html
js/
  controllers.js
  directives.js
  filters.js
  services.js
  app.js
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This works great for small, focused applications, but quickly becomes untenable
with large applications.&lt;/p&gt;

&lt;h3 id=&quot;monolithic-folders&quot;&gt;Monolithic folders&lt;/h3&gt;

&lt;p&gt;A step in the right direction, but can quickly become ridiculous. Imagine
searching through the &lt;code class=&quot;highlighter-rouge&quot;&gt;controllers/&lt;/code&gt; folder when it contains 100+ files,
trying to find the code for some obscure piece of functionality that your
product manager wants to tweak.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;js/
  controllers/
    homeController.js
    loginController.js
  directives/
    usersDirective.js
    ordersDirective.js
  filters/
  services/
    userService.js
    orderService.js
    loginService.js
partials/
  home.html
  login.html
  users.html
  orders.html
app.js
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h3 id=&quot;organize-by-feature&quot;&gt;Organize by feature&lt;/h3&gt;

&lt;p&gt;I personally like to be able to visually map what I see on the screen to the
source files that make it happen. If I am looking at the “users” page then I
expect to be able to find all of the code for it in the “users” package/folder.
Modifying the “users” page now means making changes to files in one
package/folder, instead of performing “shotgun surgery”.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;orders/
  directives/
    orders.html
    ordersDirective.js
  services/
    orderService.js
users/
  directives/
    users.html
    usersDirective.js
  services/
    userService.js
home/
  controllers/
    home.html
    homeController.js
    login.html
    loginController.js
  services/
    loginService.js
shared/
  services/
    i18nService.js
  filters/
    i18nFilter.js
app.js
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h1 id=&quot;modules-and-lazy-loading-application-components&quot;&gt;Modules and lazy loading application components&lt;/h1&gt;

&lt;p&gt;Angular Modules are good for nothing…so far. Except for loading 3rd-party
angular code into your app and mocking during testing. Other than that, there is
no reason to use more than one module in your app. Misko said of multiple
modules: “[you] should group by view since views will be lazy loaded in near
future”. I’d love for someone on the Angular team to enlighten us on what their
plans are for that.&lt;/p&gt;

&lt;p&gt;Angular does not officially support lazy loading of components. While different
workarounds exist, they can result in undefined behavior because Angular expects
everything to be loaded during the bootstrap phase. Kudos to
&lt;a href=&quot;http://ify.io/lazy-loading-in-angularjs/&quot;&gt;Ifeanyi&lt;/a&gt; on a lazy-loading solution.&lt;/p&gt;

&lt;p&gt;Here’s the basic idea:
```js
var app = angular.module(‘app’, []);&lt;/p&gt;

&lt;p&gt;app.config(function ($controllerProvider, $compileProvider, $filterProvider, $provide, $animationProvider) {
    // save references to the providers
    app.lazy = {
        controller: $controllerProvider.register,
        directive: $compileProvider.directive,
        filter: $filterProvider.register,
        factory: $provide.factory,
        service: $provide.service,
        animation: $animationProvider.register
    };&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// define routes, etc. }); ```
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Lazy-load dependencies on a per-route basis:
&lt;code class=&quot;highlighter-rouge&quot;&gt;js
$routeProvider.when(&#39;/items&#39;, {
    templateUrl: &#39;partials/items.html&#39;,
    resolve: {
        load: [&#39;$q&#39;, &#39;$rootScope&#39;, function ($q, $rootScope) {
            var deferred = $q.defer();
            // At this point, use whatever mechanism you want
            // in order to lazy load dependencies. e.g. require.js
            // In this case, &quot;itemsController&quot; won&#39;t be loaded
            // until the user hits the &#39;/items&#39; route
            require([&#39;itemsController&#39;], function () {
                $rootScope.$apply(function () {
                    deferred.resolve();
                });
            });
            return deferred.promise;
        }]
    }
});
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;itemsController.js
&lt;code class=&quot;highlighter-rouge&quot;&gt;js
// reference the saved controller provider
app.lazy.controller(&#39;ItemsController&#39;, function ($scope) {
    // define ItemsController like normal
});
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;items.html
```html&lt;/p&gt;
&lt;section data-ng-controller=&quot;ItemsController&quot;&gt;;
    &lt;!-- a bunch of awesome html here --&gt;;
&lt;/section&gt;
&lt;p&gt;;
```&lt;/p&gt;

&lt;h1 id=&quot;understand-the-scope-life-cycle&quot;&gt;Understand the $scope life cycle&lt;/h1&gt;

&lt;p&gt;$scope is the lifeblood of AngularJS. You cannot build a large application with
AngularJS and avoid the intricacies of the $scope life-cycle. The $rootScope of
your application and all of its child $scopes contain $watch expressions. There
is a $watch expression for everything you put onto $scope. This is the magic of
Angular’s two-way data-binding.&lt;/p&gt;

&lt;p&gt;Angular continuously runs what’s called a $digest loop that checks each $watch
expression to see if the value being watched has changed. If it has changed,
than Angular executes all of the listeners for that variable. This can happen
many times in a second. It is important for your watch expressions to be fast
and idempotent. Performance can become an issue if you attach functions as
$watch expressions to your $scope. These functions will be executed many times
and can slow down performance. If any of the listeners fired by changing $watch
expressions create yet more changes, which kick off more $digest loops which end
up firing &lt;em&gt;yet more&lt;/em&gt; listeners, then performance can be adversely affected.&lt;/p&gt;

&lt;h1 id=&quot;rd-party-integration-with-angularjs&quot;&gt;3rd-party integration with AngularJS&lt;/h1&gt;

&lt;p&gt;If you’ve spent any real amount of time with Angular than you’ve probably run
into problems trying to make 3rd-party libraries work with Angular. If you’re
building a large application, chances are you need to integrate several such
libraries with your app. Angular thrives on its $digest loop, giving you the
two-way data-binding magic. 3rd-party libraries don’t know what Angular does.
If your 3rd-party library changes something in the DOM, or returns you a value
via an AJAX call, Angular doesn’t know about it and continues doing its thing,
none the wiser. The keys to 3rd-party integration with Angular are
$scope.$apply(), $scope.$evalAsync, $q.when(), and $timeout.&lt;/p&gt;

&lt;p&gt;When something happens with a 3rd-party library, then you’ll probably need to
manually kick off a $digest loop via &lt;code class=&quot;highlighter-rouge&quot;&gt;$scope.$apply()&lt;/code&gt;. This way Angular can
react to whatever your 3rd-party library did. Angular’s $q promise library is a
very useful tool for asynchronously resolving the result of whatever your
3rd-party is going to do. Doing something like:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;$scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;$apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// do something with 3rd-party lib&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;$timeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// do something with 3rd-party lib&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;$timeout causes Angular to automatically do a &lt;code class=&quot;highlighter-rouge&quot;&gt;$scope.$apply()&lt;/code&gt; after the
anonymous function is executed (which isn’t executed until the &lt;em&gt;next&lt;/em&gt; browser
event loop).&lt;/p&gt;

&lt;p&gt;Learning AngularJS is a roller coaster ride, but ultimately results in increased
productivity and flexibility in building large applications.&lt;/p&gt;
</description>
        <pubDate>Thu, 01 Aug 2013 00:00:00 +0000</pubDate>
        <link>http://www.pseudobry.com/building-large-apps-with-angular-js/</link>
        <guid isPermaLink="true">http://www.pseudobry.com/building-large-apps-with-angular-js/</guid>
        
        <category>javascript,</category>
        
        <category>angular.js</category>
        
        
      </item>
    
      <item>
        <title>Power up $http with caching</title>
        <description>&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#intro&quot;&gt;Intro&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#lru_cache&quot;&gt;LRU Cache&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#setting_a_default_cache&quot;&gt;Setting a default cache&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#advanced_caching&quot;&gt;Advanced Caching&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;intro&quot;&gt;Intro&lt;/h1&gt;

&lt;p&gt;Angular.js rocks and you’re flying high making AJAX requests left and right.
Inject &lt;code class=&quot;highlighter-rouge&quot;&gt;$http&lt;/code&gt;, shoot off a request and boom—the promise-based service hits your
error or success callback.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;$http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;/foo/bar/&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;itemId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// { foo: &#39;bar&#39; }&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// uh oh&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Okay, so you’ve got your data from your backend—now what? This particular bit of
data doesn’t change very often, and you’re wondering why your client repeatedly
makes the same request for the same data—what a waste! Save your users some time
and bandwidth and tell that request to use caching!&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;$http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;/foo/bar/&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;itemId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// { foo: &#39;bar&#39; }&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// uh oh&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Sweet! Now, the first time &lt;code class=&quot;highlighter-rouge&quot;&gt;$http&lt;/code&gt; sends a &lt;code class=&quot;highlighter-rouge&quot;&gt;GET&lt;/code&gt; request to &lt;code class=&quot;highlighter-rouge&quot;&gt;/foo/bar/123&lt;/code&gt;, for
example, the response will be stored in a cache named “$http”. This cache is
created by Angular’s &lt;code class=&quot;highlighter-rouge&quot;&gt;$cacheFactory&lt;/code&gt; as the default cache for the &lt;code class=&quot;highlighter-rouge&quot;&gt;$http&lt;/code&gt;
service when Angular boots up. &lt;code class=&quot;highlighter-rouge&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;cache:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt; tells the &lt;code class=&quot;highlighter-rouge&quot;&gt;$http&lt;/code&gt; service to
cache the response to that particular request in &lt;code class=&quot;highlighter-rouge&quot;&gt;$http&lt;/code&gt;’s default cache. You
don’t have to do anything else. Any subsequent requests to &lt;code class=&quot;highlighter-rouge&quot;&gt;/foo/bar/123&lt;/code&gt; will
simply use the cached reponse. Neat!&lt;/p&gt;

&lt;p&gt;If you want you can actually reference &lt;code class=&quot;highlighter-rouge&quot;&gt;$http&lt;/code&gt;’s default cache and retrieve
items, remove items, clear the cache, etc. Just inject &lt;code class=&quot;highlighter-rouge&quot;&gt;$cacheFactory&lt;/code&gt; into
whatever you’re working with, and reference &lt;code class=&quot;highlighter-rouge&quot;&gt;$http&lt;/code&gt;’s default cache via:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$httpDefaultCache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$cacheFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;$http&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You can retrieve the cached response to the above &lt;code class=&quot;highlighter-rouge&quot;&gt;GET&lt;/code&gt; requested by using the
absolute url of the request.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cachedData&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$httpDefaultCache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;http://myserver.com/foo/bar/123&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// { foo: &#39;bar&#39; }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You can clear that item from the cache:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;$httpDefaultCache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;http://myserver.com/foo/bar/123&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Or clear the whole cache:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;$httpDefaultCache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;removeAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;See &lt;a href=&quot;http://docs.angularjs.org/api/ng.$cacheFactory&quot;&gt;$cacheFactory&lt;/a&gt; for a
complete reference.&lt;/p&gt;

&lt;h1 id=&quot;lru-cache&quot;&gt;LRU Cache&lt;/h1&gt;

&lt;p&gt;What if you don’t want &lt;code class=&quot;highlighter-rouge&quot;&gt;$http&lt;/code&gt;’s default cache to store every response? Simple:
turn it into an LRU Cache (Least Recently Used).&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Create a new cache with a capacity of 10&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;lruCache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$cacheFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;lruCache&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;capacity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Use the new cache for this request&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;/foo/bar/&#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;itemId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;lruCache&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// { foo: &#39;bar&#39; }&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// uh oh&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The reponse to each request to &lt;code class=&quot;highlighter-rouge&quot;&gt;/foo/bar/:itemId&lt;/code&gt; will be cached, but this time
the cache only has a capacity of 10. When the eleventh unique request is made
the least recently accessed item will be removed from the caching, keeping the
total number of cached items at 10. This cache maintains a list of its items in
order of how recently they have been accessed so it knows which one to remove
when storing a new item would exceed the capacity.&lt;/p&gt;

&lt;h1 id=&quot;setting-a-default-cache&quot;&gt;Setting a default cache&lt;/h1&gt;

&lt;p&gt;As shown in the LRU example you can tell an &lt;code class=&quot;highlighter-rouge&quot;&gt;$http&lt;/code&gt; request to use a cache other
than &lt;code class=&quot;highlighter-rouge&quot;&gt;$http&lt;/code&gt;’s default cache, but what if you wants to change &lt;code class=&quot;highlighter-rouge&quot;&gt;$http&lt;/code&gt;’s default
cache? It’s easy:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;$http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;defaults&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cache&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;$cacheFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#39;myNewDefaultCache&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;capacity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;$http&lt;/code&gt; will now use &lt;code class=&quot;highlighter-rouge&quot;&gt;myNewDefaultCache&lt;/code&gt; as its default cache.&lt;/p&gt;

&lt;h1 id=&quot;advanced-caching&quot;&gt;Advanced Caching&lt;/h1&gt;

&lt;p&gt;What if you want to cache data to improve user experience, but the data is
liable to change once a day, or every few hours, etc. You would want to make
sure your cached data gets cleared at least once a day, every ten minutes, etc.
Unfortunately Angular’s &lt;code class=&quot;highlighter-rouge&quot;&gt;$cacheFactory&lt;/code&gt; does not provide any such capabilities.&lt;/p&gt;

&lt;p&gt;You could hack something together using &lt;code class=&quot;highlighter-rouge&quot;&gt;setInterval()&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;setTimeout()&lt;/code&gt;, but
you don’t want to do that. To solve this problem I created &lt;a href=&quot;http://jmdobry.github.io/angular-cache/&quot;&gt;angular-cache&lt;/a&gt;,
a drop-in Angular module that gives you access to &lt;code class=&quot;highlighter-rouge&quot;&gt;$angularCacheFactory&lt;/code&gt;, which
creates caches with more capabilities. With &lt;code class=&quot;highlighter-rouge&quot;&gt;angular-cache&lt;/code&gt; your caches can
periodically clear themselves with &lt;code class=&quot;highlighter-rouge&quot;&gt;cacheFlushInterval&lt;/code&gt;. When adding to a cache
you can specify a &lt;code class=&quot;highlighter-rouge&quot;&gt;maxAge&lt;/code&gt;, which is the maximum amount of time that particular
item will be in the cache before it is automatically removed. Or you can
specify a &lt;code class=&quot;highlighter-rouge&quot;&gt;maxAge&lt;/code&gt; for the whole cache which will be applied to every item added
to the cache.&lt;/p&gt;

&lt;p&gt;I’ll refer you to the angular-cache &lt;a href=&quot;http://jmdobry.github.io/angular-cache/&quot;&gt;documentation&lt;/a&gt; for further reference.&lt;/p&gt;

&lt;p&gt;Happy caching!&lt;/p&gt;
</description>
        <pubDate>Wed, 29 May 2013 00:00:00 +0000</pubDate>
        <link>http://www.pseudobry.com/power-up-http-with-caching/</link>
        <guid isPermaLink="true">http://www.pseudobry.com/power-up-http-with-caching/</guid>
        
        <category>javascript,</category>
        
        <category>angular.js,</category>
        
        <category>caching</category>
        
        
      </item>
    
      <item>
        <title>Designing for Testability</title>
        <description>&lt;p&gt;My talk given at &lt;a href=&quot;http://lanyrd.com/2013/utahjs/&quot;&gt;UtahJSConf 2013&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do you dread writing tests? Are you frustrated with un-testable code? Wish you
had confidence in your application?&lt;/p&gt;

&lt;p&gt;What about “no pain, no gain”? Come learn design principles that will give you
confidence in your code—without the pain.&lt;/p&gt;

&lt;p&gt;Designing for testability means adhering to sound design principles. A core
benefit of solid design is insight into the internal state and activities of
your program. “Testable” doesn’t mean you can easily achieve 100% code
coverage—it means you can easily verify you’ve created the right program and
then validate your program’s correctness.&lt;/p&gt;

&lt;p&gt;Learn the What, Why, and How of:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Abstraction&lt;/li&gt;
  &lt;li&gt;Decomposition&lt;/li&gt;
  &lt;li&gt;Design by Contract&lt;/li&gt;
  &lt;li&gt;Law of Demeter&lt;/li&gt;
  &lt;li&gt;Orthogonality&lt;/li&gt;
  &lt;li&gt;Single Responsibility&lt;/li&gt;
  &lt;li&gt;DRY&lt;/li&gt;
  &lt;li&gt;Logging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beginners welcome. A must for intermediates. A great refresher for all.&lt;/p&gt;

&lt;p&gt;&lt;a class=&quot;embedly-card&quot; href=&quot;https://speakerdeck.com/jdobry/designing-for-testability&quot;&gt;Designing for Testability&lt;/a&gt;
&lt;script&gt;!function(a){var b=&quot;embedly-platform&quot;,c=&quot;script&quot;;if(!a.getElementById(b)){var d=a.createElement(c);d.id=b,d.src=(&quot;https:&quot;===document.location.protocol?&quot;https&quot;:&quot;http&quot;)+&quot;://cdn.embedly.com/widgets/platform.js&quot;;var e=document.getElementsByTagName(c)[0];e.parentNode.insertBefore(d,e)}}(document);&lt;/script&gt;&lt;/p&gt;
</description>
        <pubDate>Fri, 17 May 2013 00:00:00 +0000</pubDate>
        <link>http://www.pseudobry.com/designing-for-testability/</link>
        <guid isPermaLink="true">http://www.pseudobry.com/designing-for-testability/</guid>
        
        <category>testing</category>
        
        
      </item>
    
      <item>
        <title>i18n.js vs jquery.i18n.properties.js</title>
        <description>&lt;p&gt;Internationalization is a big deal these days, but implementing it is still a
pain sometimes. With the rise in popularity of JavaScript-heavy applications
using tools like &lt;a href=&quot;http://requirejs.org/&quot; title=&quot;Require.js&quot;&gt;Require.js&lt;/a&gt;, &lt;a href=&quot;http://backbonejs.org/&quot; title=&quot;Backbone.js&quot;&gt;Backbone.js&lt;/a&gt;,
&lt;a href=&quot;http://handlebarsjs.com/&quot; title=&quot;Handlebars.js&quot;&gt;Handlebars.js&lt;/a&gt;, etc., one naturally
seeks a solution to the internationalization problem that fits into the
paradigms of these tools. I kept a couple of points in mind while searching for
a solution:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;span style=&quot;line-height: 13px;&quot;&gt;The tool introduces no new dependencies into the build process (e.g. I don’t want to have to install Ruby)&lt;/span&gt;&lt;/li&gt;
  &lt;li&gt;The tool allows storage of i18n text in simple, easy-to-use, and preferably super common formats (e.g. JSON, or Java’s .properties)&lt;/li&gt;
  &lt;li&gt;The tool has a small footprint on projects&lt;/li&gt;
  &lt;li&gt;The tool lets me to easily access the i18n text inside my templates
I found a number of tools out there, but two jumped out at me: i18n.js (for Require.js) and jquery.i18n.properties.js&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;i18njs&quot;&gt;i18n.js&lt;/h3&gt;

&lt;p&gt;A plugin for Require.js, i18n.js loads i18n text files as dependencies. i18n
files are .js files that use the “define” wrapper function. The default i18n
file (with no locale specified) could look like this:&lt;/p&gt;

&lt;p&gt;path/to/i18n/files/i18n_module_A.js
&lt;code class=&quot;highlighter-rouge&quot;&gt;js
define({
  &quot;root&quot;: {
    &quot;someText&quot;: &quot;A short sentence&quot;,
    &quot;otherText&quot;: &quot;pink pants&quot;
  },
  &quot;ru-RU&quot;:true,
  &quot;fr-fr&quot;:false
});
&lt;/code&gt;
The “root” is the default text. “ru-RU”:true tells i18n.js that the application
supports Russian with region code RU, therefor i18n.js should expect to be able
to find files in an ru-RU folder that provide the Russian text. Therefore I
should also have the file:&lt;/p&gt;

&lt;p&gt;path/to/i18n/files/ru-RU/i18n_module_A.js
&lt;code class=&quot;highlighter-rouge&quot;&gt;js
define({
  &quot;someText&quot;: &quot;короткое предложение&quot;,
  &quot;otherText&quot;: &quot;розовые штаны&quot;
});
&lt;/code&gt;
“fr-fr”:false tells i18n.js that “fr-fr” is not supported, so even if the
browser’s locale is fr-fr, i18n.js will use the default text in “root”. If
module_A.js needs the text in i18n_module_A.js, then it loads the text like a
dependency:&lt;/p&gt;

&lt;p&gt;module_A.js
```js
define([
  ‘someDep’,
  ‘i18n!path/to/i18n_module_A’
], function (SomeDep, i18n_module_A) {&lt;/p&gt;

&lt;p&gt;// i18n_module_A is a JavaScript Object.&lt;/p&gt;

&lt;p&gt;// Prints “a short sentence” if the browser’s locale is not supported by the application
  // Prints “короткое предложение” if the browser’s locale matches “ru-RU”
  console.log(i18n_module_A.someText);&lt;/p&gt;

&lt;p&gt;// Prints “pink pants” if the browser’s locale is not supported by the application
  // Prints “розовые штаны” if the browser’s locale matches “ru-RU”
  console.log(i18n_module_A.otherText);
});
```
i18n.js also supports country codes only (e.g. “ru”):&lt;/p&gt;

&lt;p&gt;path/to/i18n/files/ru/i18n_module_A.js
&lt;code class=&quot;highlighter-rouge&quot;&gt;js
define({
  &quot;someText&quot;: &quot;короткое предложение&quot;,
  &quot;otherText&quot;: &quot;розовые штаны&quot;
});
&lt;/code&gt;
Loading the i18n text as dependencies proves to be pretty nifty. During the r.js
optimization the default text files get in-lined into the build, but there will
always end up being HTTP requests for specific country/region files. In the
Require.js callback function i18n text is loaded into a JavaScript Object
automatically, which can simple be passed to a templating engine’s render
function. The template can then pick text off the object. It made for a very
small amount of code to actually implement internationalization via i18n.js. You
simply depend on an i18n file and pass the resulting JavaScript Object to your
template. Simple.&lt;/p&gt;

&lt;p&gt;However, i18n.js requires the i18n files to be in some obscure format. If you
don’t need any server-side code (that’s not Node.js) to read these files then
it’s not a big deal, but languages like Java already use the well-known
.properties format, with which translation companies are familiar and have tools
to parse. In my case all of my i18n files are in the .properties format, so I
had to write scripts to convert the .properties files to the .js files
consumable by i18n.js, which was a hassle and an unnecessary addition to the
build process.&lt;/p&gt;

&lt;p&gt;Another thing against i18n.js is that it does not support parameterization of
strings. For example, if I need to be able to insert a user’s name into a
sentence, then I have to break the sentence up into two pieces. Very messy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final thoughts on i18n.js&lt;/strong&gt;: Trivial to setup with Require.js. Non-trivial to
make it work with other file format’s and pre-existing standards. Lack of
parameterization is a problem.&lt;/p&gt;

&lt;h3 id=&quot;jqueryi18npropertiesjs&quot;&gt;jquery.i18n.properties.js&lt;/h3&gt;

&lt;p&gt;Who wouldn’t jump at the chance to add another jQuery plugin to their site?
Luckily it’s only 4.3KB minified. The convenience of this plugin, at least for
me, is that it directly consumes .properties files. Now my Java services can
consume the same i18n files as the frontend.&lt;/p&gt;

&lt;p&gt;Messages.properties
&lt;code class=&quot;highlighter-rouge&quot;&gt;
# This line is ignored by the plugin
msg_hello = Hello
msg_world = World
msg_complex = Good morning {0}!
&lt;/code&gt;
Messages_ru_RU.properties
&lt;code class=&quot;highlighter-rouge&quot;&gt;
# This line is ignored by the plugin
msg_hello = привет
msg_world = мир
msg_complex = доврое утро {0}!
&lt;/code&gt;
.properties files are loaded with an Ajax call:&lt;/p&gt;

&lt;p&gt;Loading a .properties file
```js
// This will initialize the plugin
// and display “Good morning John!”
jQuery.i18n.properties({
  name:’Messages’,
  path:’path/to/i18n/files/’,
  mode:’map’,
  language:’ru_RU’,
  callback: function() {
    // I specified mode: ‘map’ because the ‘vars’ mode
    // will add a lot of global JS vars to the page.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// Accessing a simple value through the map
$.i18n.prop(&#39;msg_hello&#39;);

// prints &#39;привет&#39;
alert($.i18n.prop(&#39;msg_hello&#39;));   } }); ``` Another great plus for this plugin is that is supports parameterization:
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;parameterization
&lt;code class=&quot;highlighter-rouge&quot;&gt;js
// prints доброе утро John!
alert($.i18n.prop(&#39;msg_complex&#39;, &#39;John&#39;));
// does the same as above
alert($.i18n.map.msg_complex(&#39;John&#39;));
&lt;/code&gt;
Initially I was worried that using this plugin would result in a lot more lines
of code in the JavaScript, as I thought that I would need to manually extract
each line of text from the .properties files. This plugin does not put all of
the i18n text into a JavaScript object like the i18n.js plugin does. However, it
was rather simple to write a helper for Dust.js that allows me to access i18n
strings loaded by jQuery directly in my templates:&lt;/p&gt;

&lt;p&gt;Dust.js helper
&lt;code class=&quot;highlighter-rouge&quot;&gt;js
dust.helpers.i18n = function (chunk, ctx, bodies, params) {
  var key = dust.helpers.tap(params.key, chunk, ctx);
  return chunk.write($.i18n.map[key]);
};
&lt;/code&gt;
and then in the template:&lt;/p&gt;

&lt;p&gt;Accessing i18n strings in the template
```html&lt;/p&gt;
&lt;h1&gt;
  {@i18n key=&quot;msg_hello&quot; /}
&lt;/h1&gt;
&lt;p&gt;```
&lt;strong&gt;Final thoughts on jQuery.i18n.properties.js&lt;/strong&gt;: I really appreciate this
plugin’s support for parameterization of strings. More importantly, it consumes
.properties files which is excellent.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;With the help of the Dust.js helper function it ends of being much more
convenient to work with the jQuery.i18n.properties.js plugin, rather than the
i18n.js plugin for Require.js. I haven’t looked deeply into other solutions for
internationalization, but the jQuery plugin meets my needs just fine.&lt;/p&gt;
</description>
        <pubDate>Wed, 06 Feb 2013 00:00:00 +0000</pubDate>
        <link>http://www.pseudobry.com/i18n-js-vs-jquery-i18n-properties-js/</link>
        <guid isPermaLink="true">http://www.pseudobry.com/i18n-js-vs-jquery-i18n-properties-js/</guid>
        
        <category>require.js,</category>
        
        <category>javascript,</category>
        
        <category>i18n.js,</category>
        
        <category>jquery</category>
        
        
      </item>
    
      <item>
        <title>Maven and r.js optimization</title>
        <description>&lt;p&gt;Using Maven to manage a large project has it’s advantages, until you need to do
something that doesn’t fit into the Maven’s defined context. Tools based on
composability provide components that can be combined in various ways to
accomplish needed tasks. Maven—a contextual tool—provides a lot of functionality
out of the box, but ultimately requires users to conform to Maven’s way of doing
things, not allowing the user to simple string together commands to perform
custom tasks.&lt;/p&gt;

&lt;p&gt;I personally am a big fan of using &lt;a href=&quot;http://gruntjs.com/&quot;&gt;Grunt.js&lt;/a&gt;—a composable
tool—for performing tasks on my JavaScript (like r.js optimization). However,
Grunt introduces a dependency on Node.js—a JavaScript run-time. Maven’s design
does not sit well with running external scripts during a Maven build. How can
these scripts communicate back to Maven and report on their success, failure, or
something in between? They can’t. Maven watches for a successful return code,
but that’s it. External scripts are used because Maven didn’t provide the tools
to perform the tasks, so 3rd-party tools were brought into the picture. But
because the extra tools weren’t grown in Maven’s context, they’re on their own.&lt;/p&gt;

&lt;p&gt;I messed around with having Maven run external node.js scripts for a while, but
it was ugly. I decided to give mcheely’s &lt;a href=&quot;https://github.com/mcheely/requirejs-maven-plugin&quot;&gt;requirejs-maven-plugin&lt;/a&gt;
a try. His plugin takes the r.js optimizer and shoves it into Maven’s context.
And you know what? It works pretty well.&lt;/p&gt;

&lt;p&gt;Configuration can be as simple as:
```xml&lt;/p&gt;
&lt;plugin&gt;
  &lt;groupId&gt;com.github.mcheely&lt;/groupId&gt;
  &lt;artifactId&gt;requirejs-maven-plugin&lt;/artifactId&gt;
  &lt;version&gt;1.0.4&lt;/version&gt;
  &lt;executions&gt;
    &lt;execution&gt;
      &lt;phase&gt;process-classes&lt;/phase&gt;
      &lt;goals&gt;
        &lt;goal&gt;optimize&lt;/goal&gt;
      &lt;/goals&gt;
    &lt;/execution&gt;
  &lt;/executions&gt;
  &lt;configuration&gt;
    &lt;configFile&gt;${basedir}/src/main/webapp/resources/js/app.build.js&lt;/configFile&gt;
    &lt;!-- whether or not to process config with maven filters --&gt;
    &lt;filterConfig&gt;false&lt;/filterConfig&gt;
    &lt;!-- Skip requirejs optimization if true --&gt;
    &lt;skip&gt;false&lt;/skip&gt;
  &lt;/configuration&gt;
&lt;/plugin&gt;
&lt;p&gt;```&lt;/p&gt;

&lt;p&gt;By using this plugin (and a few others like the &lt;a href=&quot;http://samaxes.github.com/minify-maven-plugin/&quot; title=&quot;minify-maven-plugin&quot;&gt;minify-maven-plugin&lt;/a&gt;)
here at work we’ve successfully eliminated our dependency on Node.js for builds,
which makes development environments easier to setup for everybody and means
less things for Java developers to have to learn. I have nothing against Node.js
here—I really like it, but the existence of plugins like this make life with
Maven (and other devs) a little easier.&lt;/p&gt;
</description>
        <pubDate>Fri, 01 Feb 2013 00:00:00 +0000</pubDate>
        <link>http://www.pseudobry.com/maven-and-r-js-optimization/</link>
        <guid isPermaLink="true">http://www.pseudobry.com/maven-and-r-js-optimization/</guid>
        
        <category>maven,</category>
        
        <category>r.js</category>
        
        
      </item>
    
  </channel>
</rss>
