Wednesday, November 2, 2011

How to build a webapp with CouchApp and CouchDB

This is a chronicle of the additional work I had to do as I followed Ed Parcell's Tutorial: Using jQuery and CouchDB to build a simple AJAX web application. It is supposed to serve as a supplement.

Ed's post covers the use of CouchApp as far as generating templates to work on is concerned. As a supplement, my post will leverage the Evently framework (already a part of the generated CouchApp 0.8.1) to do the same exact thing.
  1. When asked to edit index.html for the first time in Ed's post, here is how the content will differ if you want to do things the Evently way:
    <!DOCTYPE html>
      <html>
    
      <head>
        <title>Address Book</title>
        <link rel="stylesheet" href="style/main.css" type="text/css">
      </head>
    
      <body>
        <h1>Address Book</h1>
        <div id="add"><button type="button" id="add">Add</button></div>
        <div id="addressbook"></div>
      </body>
    
      <script src="vendor/couchapp/loader.js"></script>
    
      <script type="text/javascript" charset="utf-8">
        $.couch.app(function(app) {
          $("#addressbook").evently("addressbook", app);
        });
      </script>
    </html>
    
  2. Lets take a moment to acknowledge all the differences:
    1. Links to json2.js, jquery.js or jquery.couch.js are not present in the head section. This is now taken care of by loader.js (view source +/-), which loads all of the required javascript files.
    2. An additional script section:
      $.couch.app(function(app) {
            $("#addressbook").evently("addressbook", app);
          });
      
      is used to wire-up the addressbook div element with an evently widget (also named addressbook but the names don't really have to match, its not a requirement) which we will be writing later in this tutorial.
  3. The Evently approach also mandates a rewrite of Ed's refreshAddressbook function such that the html and javascript are placed in separate files and tied together via the use of the Mustache template engine. So instead of injecting any more javascript into your index.html, follow these steps:
    1. Navigate to the addressbook directory, which was generated by couchapp for you when you ran, in the past:
      couchapp generate app addressbook
      cd addressbook
      
    2. Create an evently widget named addressbook by simply creating the appropriate directory structure:
      mkdir -p evently/addressbook/
      
    3. Create _query.js file to hold the view which should be loaded from CouchDB when the addressbook div element is hooked-up with the addressbook widget (refer to line # 19 in index.html source provided earlier):
      function () {
        $.log('Inside evently/addressbook/_init/query.js');
      
        return {
          "view" : "phonenumbers",
        };
      }
    4. Create data.js file to process the data returned by CouchDB which will be available for the Mustache template engine's use:
      function(data) {
        $.log('Inside evently/addressbook/_init/data.js');
        $.log(data.rows);
        return {
          "addressbook" : data.rows
        };
      }
    5. Create mustache.html file to substitute the data and render the html directly into the addressbook div element:
      {{#addressbook}}
      <div class="address">
        <span class="name">{{key}}</span>
        <span class="phonenumber">{{value}}</span>
        <a href="#edit" class="edit">edit</a>
        <a href="#delete" class="delete">delete</a>
      </div>
      {{/addressbook}}
      
    6. Uplaod the app:
      couchapp push
    7. Before we go any further let's test what we've written so far. You'll notice that I've thrown in logs and alerts into the javascript above. If all is well then we should see an alert pop up with the data being retrieved from the server. Also if you have debugging tools like Firebug or Web Inspector at your disposal, then you should be able to see the data printed out in the console.
      1. Safari and Firefox on my mac work well and I hope that you too see a popup stating [object Object] and your console output looks something like:
        Entering view callback in evently/addressbook/_init.js
        jquery...util.js (line 3)
        Object { total_rows=2, offset=0, rows=[2]}
        jquery...util.js (line 3)
        Exiting view callback in evently/addressbook/_init.js
        
      2. B U T ... if you head over to your iPhone's safari browser and try the same thing, you may be in for a huge disappointment! Nothing will happen. And if you enable the Debug Console, you'll see javascript errors stating that jQuery does not exist!
        • If you run into this then based on the wisdom gleaned from this post on stackoverflow, here's what you need to do:
          1. Get all the supporting JS files listed under the _utils URL to be directly present in your own addressbook couchapp:
            cd vendor/couchapp/_attachments/
            wget http://fermyon.iriscouch.com/_utils/script/jquery.couch.js
            wget http://fermyon.iriscouch.com/_utils/script/sha1.js
            wget http://fermyon.iriscouch.com/_utils/script/json2.js
            wget http://fermyon.iriscouch.com/_utils/script/jquery.js
            
          2. Update loader.js to serve the files out of your own addressbook couchapp:
            vi vendor/couchapp/_attachments/loader.js
            
            ...
            couchapp_load([
              "vendor/couchapp/sha1.js",
              "vendor/couchapp/json2.js",
              "vendor/couchapp/jquery.js",
              "vendor/couchapp/jquery.couch.js",
              "vendor/couchapp/jquery.couch.app.js",
              "vendor/couchapp/jquery.couch.app.util.js",
              "vendor/couchapp/jquery.mustache.js",
              "vendor/couchapp/jquery.evently.js"
            ]);
            
        • If things are still breaking then there is one other analysis & workaround for this dilemma presented here in a blog post by Lee Boonstra.
        • If you are still having issues then use the Safari on your Mac's iOS Simulator to browse the couchapp because it gives more detailed information in its Debug Console than the actual browser on the iPhone. If you are still seeing something like the following image:
          Then you still haven't fixed the problem as described in the steps above so go back and make sure you follow all the instructions to get it resolved.
    8. Now lets finish off editing _init.js:
      put code here...
      
  4. mustache stuff

0 comments:

Post a Comment