Anas Nakawa

× - +

Resetting Knockout Observables



I used to see developers defining knockout observables somewhere in their modules, and later when hiding the module they go and reset those observables with the same value the observable has been initialized with.

not a big deal, but the more you have observables in your module, the more annoying it will become to reset them.

life should be easier, and as developers we always have the choice to make things easier for us. the problem we're facing here, is that we shouldn't provide the default value twice. once you define an observable, you know what default value for this observable should be.

so the trick here is to come up with an easy way to tell the observbale when you initialize it that this is your default value.

I did a tiny extension to the knockout that hopefully will ease the pain here, let me show you the code:

// adding default value when initializing an observable
// for later resetting, preventing the observable from
// becoming undefined ( still you can set it to `null` )
// ====================================================
// example[1]: primitive types ( passed by value )
// -----------------------------------------------
// var username = ko.observable().default( 'guest' );
// username();              // 'guest'
// username( 'admin' );     // 'admin'
// username( undefined );   // 'guest'
// username( 'john doe' );  // 'john doe'
// username.reset();        // 'guest'
//
// example[2]: non-premitive types ( passed by reference )
// -------------------------------------------------------
// var userList = ko.observableArray([]).default(function() { return []; });
// var settings = ko.observable().default(function() { return { foo: 'bar' } });
// userList.reset();
// settings.reset();
ko.observable.prototype.reset = function() {
  this( typeof this._default === 'function' ? this._default() : this._default );
}

// * **param:** {object|factory}
ko.observable.prototype.default = function( value ) {
  if( typeof value === 'undefined' ) {
    return;
  }

  // store default value
  this._default = value;

  // observable defined with no arguments
  // use default
  typeof this() === 'undefined' && this.reset();

  // whenever value changed to undefined, reset to default
  this.subscribe(function( newValue ) {
    typeof newValue === 'undefined' && this.reset();
  });
}

after you include this tiny extension to your application ( Note that it should be added after loading knockout.js file ), you can define your own observable using the default extension as follows

this.price = ko.observable().default( 0 );

// this.observableArray([] ).default([ ]) will not work, because array is passed by reference
// so second time you do a reset, it won't work
this.itemList = ko.observableArray([ ]).default( function() { return [ ] });

// for the same previous reason, we use a factory to generate the default value
this.config = ko.observable().default( function() { return {} });

later when you want to reset those observables, you can call the reset method..

// later you can reset it like this
this.price.reset();
this.itemList.reset();
this.config.reset();

and in case you don't like to reset every observable

for( var obs in this ) {
  ko.isObservable( this[ obs ] ) && this[ obs ].reset();
}

Note here that when our default value is a primitive, we just pass it to the default method as is, while when our default value is an Array or an Object, we need to provide the default value using a factory method, and thats because unlike primitives, Arrays and Objects are passed by reference, so the factory method here will make sure everytime we do a reset, we'll get a fresh copy of the desired default value.

hope it will ease your life a bit :)


Blogging with Docpad



it has been a while since my last blog post, which happened over 2 years ago..

usually i am not that active blogger, maybe because I wasn't feeling comfortable with the blog engines out there, also lets not forget that most of the times i am a lazy person, especially when it comes to writing posts.

Why I hated blog engines ?

actually I think blog engines ( such as Wordpress, tumblr ..etc ) are great for writing posts for most people, but when it comes to a developer like me sometimes I just don't feel that I have the freedom that I want..

either if I want to share a code snippet with some fancy syntax highlighting, or if I want to provide some live demo, both ways I will end up looking for some plugin to satisfy my needs ... not exactly what I was looking for.

the answer should be much simpler, all I need is to write HTML/CSS & JS code at my convenience, and that was not much to ask.

A better alternative..

Last year I started to hear about somthing called static site generators, I even started to see some great front-end developers shifting their blogs into one of these generators..

first I was surprised that most static site generator implementations out there were built on ruby ( e.g: Jekyll, Octopress ), but since I am a javascript guy, I was looking for something more familiar to me...a Node Js implementation, and found that Docpad was exactly what I was looking for.

getting started with docpad was straight forward, they have some nice set of pre-built skeletons, so I cloned their Bootstrap Skeleton, and got my hands on this nice technology..

Design inspiration

it is worth mentioning that this site was not only inspired by Orman's Clark great designs, I actually transofmed his Code Editor App completly into what you see over here.

Code Editor App - By Orman Clark

Site code

you can find the source code of this site hosted on Github, go a head make a fork, and have it at your own site, I will be more than happy :)