jschain: React and browserify (#5)

I made a little sign-up form example with React.

I built it in RequireBin. The main react model in isn’t working in RequireBin and I’m working to get it fixed. In the meantime I’ve published benatkin-react to npm which makes the minimal changes needed to get it to work (none to the code, just to the packaging).

The sign-up form I made has validation which highlights invalid fields with red after an attempt has been made to enter it in correctly.

jschain: parafocus (#1)

This month my goal is to post a small JavaScript project every day of the month. Today’s project is an angular.js app for jumping between paragraphs using the keyboard. Besides navigating between paragraphs it can show paragraphs before or after the current paragraph without leaving the page. This could help if the reader needs to recall a detail from the last paragraph in order to fully understand the current paragraph.

I used these resources to help me get it done:

  • How to listen for key presses with AngularJS – showed me that I wanted was keydown events on the body tag using ng-keydown
  • 5apps – a lot like GitHub pages with Jekyll turned off, except I don’t need to create another branch. Unlike Heroku, free apps don’t go to sleep.

hood.ie

I tried out hood.ie today after hearing about it a few times and I think it’s worth giving a shot, if you’re interested in rich web applications. It’s easy to install for what it does, which is set up a local node.js and couchdb environment with an admin interface. Deployment looks like it will be really easy, too.

Borrowing Backbone’s extend function

If you want to use Backbone.js’s extend function on your own class, all you have to do is this:

var LightModel = function(attributes, options) {
  this.attributes = _.extend({}, attributes);
}

_.extend(LightModel.prototype, Backbone.Events, {
  get: function(key) { return this.attributes[key]; },
  set: function(key_or_values, value) {
    if (typeof key_or_values == 'string') {
      this.attributes[key_or_values] = value;
    } else {
      _.extend(this.attributes, key_or_values);
    }
  }
});

LightModel.extend = Backbone.extend;

Backbone’s extend function is the same between Backbone’s classes. It just uses the prototype it was called with. MyModel1 and MyModel2 in the following example would be equivalent:

var MyModel1 = Backbone.Model.extend({});
var MyModel2 = Backbone.View.extend.call(Backbone.Model, {});

ANN: js2json and json2js (for CouchApps)

Here’s a copy of the email I sent to the CouchDB users mailing list:

I made a couple of npm (node.js) modules for editing CouchDB design documents that involves fewer files than python CouchApp, but like python CouchApp supports two-way sync. The function source is left intact when converting between JavaScript source and JSON. The JavaScript source version just shows it in an embedded function expression, which makes it syntax highlightable.

http://benatkin.com/2012/09/04/js2json-and-json2js/
https://github.com/benatkin/js2json
https://github.com/benatkin/json2js

Here’s a quick example. If I stick this in books.js:

module.exports = {
  "views": {
    "author": {
      "map": function(doc) {
        if (doc.type == 'book')
          emit(doc.author, null);
      }
    },
    "title": {
      "map": function(doc) {
        if (doc.type == 'book')
          emit(doc.title, null);
      }
    }
  }
}

…and run this (after npm install json2js js2json):

var js2json = require('js2json');
var json2js = require('json2js');
var fs = require('fs');

var jsSource = fs.readFileSync('books.js', 'utf8');
var jsonValue = js2json.convert(jsSource);
fs.writeFileSync('books.json', JSON.stringify(jsonValue, null, 2) + "\n");
var jsSourceFromJson = json2js.convert(jsonValue);
fs.writeFileSync('books-from-json.js', jsSourceFromJson + "\n");

…I get the following in books.json:

{
  "views": {
    "author": {
      "map": "function(doc) {\n  if (doc.type == 'book')\n
emit(doc.author, null);\n}"
    },
    "title": {
      "map": "function(doc) {\n  if (doc.type == 'book')\n
emit(doc.title, null);\n}"
    }
  }
}

…and books-from-json.js is exactly the same as books.js.

I explain it more in my blog post (linked at the top of this message). I need to add a cli tool that syncs, a way to handle attachments, and a way to handle embedded multiline strings for it to be a full-featured design doc editor. I have much bigger plans for this, though: I want to break up CouchApps into a bunch of smaller documents! The source and tests for these two modules is programmed in the same style. I think storing functions in JSON makes CouchDB just a little bit like Smalltalk, with a much more familiar language.

Thanks for reading. Feedback welcome and appreciated.