Saturday, December 28, 2013

javascript internals: scopes

Now here is something that can definitely tease the programmer in you.

Someone in stackoverflow asked a question related to javascript. It goes something like this:

Snippet 1:

<script type="text/javascript">
	function MyFunc() {
		alert(1);
	}
	var f1 = MyFunc;	
	function MyFunc() {
		alert(2)
	}
</script>
<script type="text/javascript">

</script>
<script type="text/javascript">
	f1();	
</script>

f1() outputs 2 in a message box. This is acceptable and expected.

Snippet 2: 

<script type="text/javascript">
    function MyFunc() {
        alert(1);
    }
    var f1 = MyFunc;
</script>
<script type="text/javascript">
    function MyFunc() {
        alert(2)
    }
</script>
<script type="text/javascript">
    f1();
</script>
 f1() outputs 1.

Wait...what the hell just happened? Isn't the above two snippets equivalent?

You can try it out at jsbin, or jsfiddle, or whatever place, but you'd still end up with the same observation.

My answer relates the idea of scoping that takes place in a script block. A whole new scope is created for the entire code inside a script block to run in. Hence for our 2nd case, we have MyFunc defined in scope 1 - i.e. the scope of the first script block. So MyFunc is now an object which is created with scope 1. f1 now points to this object.

When the second script block is executed, we have MyFunc created in a new scope. Hence a new object is created in that scope. So the MyFunc created in the first scope is not the same MyFunc created in the second scope. They are essentially two separate objects. And now since f1 points of the first object created; calling the method pointed by it will output a message box saying 1.

In the first snippet. The object is created only once. However, MyFunc is defined twice in the same scope. Hoisted I believe is the correct term to use here. So, one object is created, and, that object, is associated with the most recent definition. Hence the call to f1 will output a message box saying 2.

Upvote my answer if you agree with the explanation, else you can provide your own comments there.

Happy programming...

Thursday, October 10, 2013

the csv file problem?!

Do you know what a csv file is...? Even if you don't have experience, you could at least try some cloud based spreadsheet app like Google Spreadsheet. Even products like MS Excel give you options to save your worksheet to a CSV format. Basically open one such app, type in data in a few contiguous columns and rows...and then when it comes to saving you have the option of saving it as a Comma Separated Value or CSV.

The final result will look similar to this when opened in a plain vanilla text editor:


So now you know why its "comma" separated...however to be more generic, people can be a little uneasy with that character, hence they resolve to use some other character like a tab ('\t'), or a pipe ('|'), etc.

Hence to be more generic we should be calling this pattern of data storage Delimiter-Separated-Value or DSV. This pattern of storage is meant to store tabular data via a series of delimiters (to separate columns) and row-terminators (or line-terminators).

Now comes the more tricky problem...

Imagine there is program that would parse dsv files given its delimiter and row-terminator. You are only provided with a dsv file with no knowledge of the above two things...how do you write a program to find those two things out?!

Drop in a comment if you happen to figure this out or if you want an answer to it.

Happy programming.

Wednesday, October 2, 2013

subscribing to your observable in knockout.js

Whenever you have array like data in your view-model, you'd want to display in a tabular format. Assume each object in that array has observable properties; and you bind one of these properties to a text box so that user can type in the value, and thereby achieve two-way binding.

<table>
	<tbody data-bind="foreach: students">
		<tr>
			<td data-bind="text: name"></td>
			<td data-bind="text: age"></td>
			<td>
				<input type="text" data-bind="value: grade"/>
			</td>
		</tr>
	</tbody>
</table>
Now what about the text box that is created for you...dynamically?

Now imagine you want to wire some jQuery UI stuff to this text box. Most of the jQuery ui api applies to elements which are part of the DOM. The text box created in the above fashion, may usually be a part of the DOM at a later stage. The previous post describes how you can wire a jquery autocomplete to one such dynamically created text box.

All of this is fine. But now I am going to introduce another topic in knockout.js, which does not seem connected to all of this...but then it somehow will be.

The concept is called a subscribable. The knockout.js framework gives you two-way binding, or, in other words, a two-way subscription. Its because of this, your model is updated when a user types something into a knockout-bound text box, and vice versa.


But what if you are simply just interested in subscribing to changes to a observable somewhere in code such that you don't need any kind of ui-bound logic tied to it?

This is where you'd want to use the subscribe method of the observable. It usually takes the form:
function ViewModel(){
    this.name = ko.observable('');
}

var model = new ViewModel();

model.name.subscribe(function(value){
    //some logic goes here
});

Now whenever we do something like model.name('Alice'), the function inside of subscribe is executed and Alice is passed as an argument to it.

Now lets go back to our jquery autocomplete exercise. Does all this yet give you an idea as to how you can improve the functionality of autocomplete, and thereby achieve two-way binding?

OR

Friday, September 20, 2013

knockout with jQuery Autocomplete


Today we are going to look at how to implement a jQuery autocomplete feature against a UI which is bound to a model via knockout bindings. And in this exercise you'd also learn about how to write your custom bindings using knockout's framework.

So in this exercise I am simply going to write a small app which is going to list some task and allow us to assign some user to the task. Here is the example below:

jQuery autocomplete with knockout.js
The important parts in the code are:

1. The data-bind declaration for the textbox

<input type="text" 
    data-bind="value: name, autoComplete: {label: name, value: id}"/>

2. The custom binding declaration

ko.bindingHandlers.autoComplete = {
  init:function(el, va, ba, vm, ctx){
    var prop = va();
    $(el).autocomplete({
      source: users,
      select: function(evt, ui){
        evt.preventDefault();
        var item = ui.item;
        console.log(item);        
        prop.label(item.label);
        prop.value(item.value);
      }    
    });      
  }
};

Knockout exposes a bindingHandler property via which we add a new property. That property can have any methods defined in it, but the following two are reserved for knockout – init & update.

The two functions have the same signature:


ko.bindingHandler.yourCustomHandler = {
    init: function(element, valueAccessor, bindingAccessor, viewModel, bindingContext){
        //logic
    }
};

init is called when a particular dom element is created in the context of binding. update is called whenever there are any changes in the model. To get more idea about the arguments these functions have, visit the knockout docs.

We've used only the init function since that is the only one required.

But what is the significance of the value binding there?

Without the value binding there wouldn't be a two-way binding per se.

The autocomplete part is pretty much self explanatory. This app is fairly simple. The autocomplete options don't take part in the model. However, if they did, that would have to be in a different blog post all together.

Can we do the same exercise without the value binding?!
+ me on Google Plus if you figure that out!... ;)

Friday, July 19, 2013

knockout.js

How this library sells itself?
  • Its not jQuery.  
  • It attaches to DOM level elements and all, however it doesn't provide a mechanism to traverse the DOM via selectors (like jQuery does) or via any other mechanism. 
So now the question comes...where then do you use it?

If you are a novice programmer, and you've just begin to like jQuery, chances are that you'd tend to build complex web pages without much concern on how to manage the huge amount of data your web page might be holding. There might be ajax callbacks which update the data, and subsequently you are writing code to add new DOM elements to the web page or update the existing DOM elements correspondingly.

However, when moving up from that novice state to a relatively more experienced state you'd begin to think if there is anything out there which would save you from updating DOM each time your data (or some part of it) updates or refreshes from the server...your experience might call out to you and say, no there’s got to be a better way to do this...enter knockout.js

Now this library is not a replacement for jQuery or any other library which serves to be a low-level DOM api. It is meant to complement it.

To really appreciate the power of knockout.js study the example below:

To simply add a new row to the table, I didn't have to write any DOM level api stuff like document.createElement, document.getElementById, or, go through the headache of appending it as a child of the students table element, etc.

Hope you've enjoyed the small example. Happy programming...

Hey!! Why not play around with the fiddle?! Try adding a delete functionality to this table and find out how easy that goes. You can paste a link to that fiddle in the comments below...