Understanding click binding in Knockout.js

Click Binding adds click event to element on View. You can do click binding with any function in ViewModel or you can bind to any normal function.

clip_image001

Let us try to understand it with a very simple ViewModel. We have a ViewModel as below

 var viewModel =
 {
 display: function ()
 {
 console.log("display");
 }
 }

As you see there is one function as property of ViewModel and that can be click bind on view as below,


<button data-bind="click:display" >display</button>

Let us consider one more example and in this we will update value of other observable on click of element on View. We have ViewModel as below,


var viewModel =
 {
 count : ko.observable(0) ,
 display: function ()
 {
 this.count( this.count() + 1);
 }
 }

On View we are doing click binding and text binding as below


<button data-bind="click:display" >display</button> <br/>
 Number of clicks <span data-bind="text:count" ></span>

Sometime you may have to pass current item in click binding. Assume a requirement that you have done foreach binding on element with observable array. Now on click of a particular item, you need to pass that item in ViewModel function to work with that. That can be solved as below. As you see in below ViewModel,

  • There is an observable array. This will be bind to ul or tr element on View
  • There is a function. It takes input which will be used to delete item from observable array.

function viewModel()
 {
 var self = this ;
 self.subject= ko.observableArray(["Phy", "Che", "Bio"]),
 self.removeSubject= function (item)
 {

 self.subject.remove(item);
 }
 }


ko.applyBindings(new viewModel());

On the View we need to do click binding and pass current item to function on which click binding is getting performed.


<ul data-bind="foreach: subject">
 <li>
 <span data-bind="text: $data"></span>
 <button data-bind="click: $parent.removeSubject">Remove</button>
 </li>
</ul>


If you notice we are passing current item using current binding context. So to pass current we are using parent.

In some scenario you will have to pass event object. Event object can be passed as given below,


function viewModel()
 {
 var self = this ;
 self.subject= ko.observableArray(["Phy", "Che", "Bio"]),
 self.removeSubject= function (data,event)
 {
 if (event.shiftKey) {
 self.subject.remove(data);
 }
 }
 }


On View binding can be done as below


<ul data-bind="foreach: subject">
 <li>
 <span data-bind="text: $data"></span>
 <button data-bind="click: $parent.removeSubject($data,event)">Remove</button>
 </li>
</ul>

&nbsp;

Now an item would be deleted on pressing shift key . Understanding of click binding is very useful to create apps using KO. I hope you find this post useful. Thanks for reading.

Create REST API on Node.js using Visual Studio

Find Source Code on Github

In this post I am not going to explain, what is REST? I assume you are already aware of REST concepts hence on this post to create REST API on Node.js which will perform CRUD operations. I am going to use Visual Studio to create Node Application and before you move ahead in this post, recommend you to read

Getting started with Node.js development in Visual Studio

After reading above article when you are done with setting up Visual Studio for Node.js go ahead and create a Node Application by selecting Blank Express Application template from JavaScript language section

image

Once project is created right click on the public\javascripts folder and add a new JavaScript file. You are free to give any file name, I am giving data.js .

Before you work with data.js I recommend you to read below post

Working with modules

First we are going to create data and CRUD operation on that. Keep in mind that we are going to expose CRUD operation as REST API on a JavaScript Array. In real projects you may want to perform these operations on database.

To start with I have created an array as below,


var product =
[
 {
 "id" :1 ,
 "productName" : "Pen",
 "productPrice" : "200",
 'productStock' : "false"
 },
 {
 "id" :2 ,
 "productName" : "Pencil",
 "productPrice" : "200",
 "productStock" : "false"
 },
 ];

Fetch Records

Let us start with writing function to return products. If you notice function is taking two parameters req and res. We send data in HTTP response with res.send . In this case we are sending JSON object product as HTTP response.


exports.getProducts = function(req,res){

 res.send(product);
 };

Add Record

To add record we need to read data coming in HTTP request. We can read that using req.body. Client will append JSON data to get added in product array in request body. After reading request body we are just pushing data in array using push method.

 


exports.addProduct = function(req,res)
{
 var data = req.body;
 product.push(data);
 res.send(product);
}

Delete Record

To delete record we need to read query parameter coming in URL as HTTP request. We can read that using req.params. Once we have id to delete a product, I am just putting some logic to delete it from products array. Keep in mind that in real project and API this logic should be better. Once product is deleted successfully we are sending updated product JSON object in HTTP response.


exports.deleteProduct = function(req,res)
{

 var id = parseInt(req.params.id)-1;
 var itemdeleted = product.splice(id,1)
 if(itemdeleted===undefined)
 {
 res.send("Not Deleted");
 }
 else
 {
 ;
 res.send(product);
 }
}

Update Record

To update record we need to read query parameter coming in URL as HTTP request. We can read that using req.params. Once we have id to update a product, we will read data to be updated in req.body. After that I am just putting some logic to update item in products array. Keep in mind that in real project and API this logic should be better. Once product is updated successfully we are sending updated product JSON object in HTTP response.


exports.updateProduct = function(req,res)
{
 var id = parseInt(req.params.id)-1;
 var productToUpdate = product[id];
 var data = req.body;

 if(productToUpdate===undefined)
 {

res.send("Not Updated");
 }
 else
 {
 productToUpdate.productName = data.productName;
 productToUpdate.productPrice = data.productPrice;
 productToUpdate.productStock = data.productStock;

res.send(product);
 }

}

 

Just we created CRUD operation which we will expose as REST API. Putting all together data.js which contains logic for CRUD would be as below,

data.js

var product =
[
 {
 "id" :1 ,
 "productName" : "Pen",
 "productPrice" : "200",
 'productStock' : "false"
 },
 {
 "id" :2 ,
 "productName" : "Pencil",
 "productPrice" : "200",
 "productStock" : "false"
 },
 ];
exports.getProducts = function(req,res){

 res.send(product);
 };

exports.addProduct = function(req,res)
{
 var data = req.body;
 product.push(data);
 res.send(product);
}

exports.deleteProduct = function(req,res)
{

 var id = parseInt(req.params.id)-1;
 var itemdeleted = product.splice(id,1)
 if(itemdeleted===undefined)
 {
 res.send("Not Deleted");
 }
 else
 {
 ;
 res.send(product);
 }
}

exports.updateProduct = function(req,res)
{
 var id = parseInt(req.params.id)-1;
 var productToUpdate = product[id];
 var data = req.body;

 if(productToUpdate===undefined)
 {

res.send("Not Updated");
 }
 else
 {
 productToUpdate.productName = data.productName;
 productToUpdate.productPrice = data.productPrice;
 productToUpdate.productStock = data.productStock;

res.send(product);
 }

}

&nbsp;

So far we have created business logic to be exposed as REST API. Now we need to add various routes in app.js. These routes will call functions from data.js module. We are going to map ROUTES to business logic as below,

image

Open app.js and add this code to load data.js module. [write all below code in app.js]


var data = require('./public/javascripts/data.js');

Once module is loaded use bodyParse to parse request body.


app.use(express.bodyParser());

If you notice we created project using Express Template. So here Node.js Express Framework router is being used. In last step to create REST API we need to add routes to application.


app.get('/products',data.getProducts);
app.post('/products',data.addProduct);
app.delete('/products/:id',data.deleteProduct);
app.put('/products/:id',data.updateProduct);

Each route is calling a function in data module. If you notice when we added a route for HTTP POST operation which is calling addProducts function. In this function we are creating a product.

Yes it is done. You have created REST API on Node.JS using Visual Studio. To test it you have various options. You can either use

  • CURL
  • Fiddler
  • Create a client to work with service (in next post we will do this)

So let us test created REST API in Fiddler and browsers. We can test HTTP GET in browser by pressing F5 and navigate to baseURL/products

image

Next let us use fiddler to perform POST, PUT and DELETE. To perform POST or create a product select Composer, from drop down select POST operation. Set URL, set Content-Type and in Request-Body construct a JSON to add as product.

image

When you perform this operation as a response you will get updated products as response. You can verify this in browser as well.

image

As you performed POST in the same way in fiddler you can perform DELETE and PUT. So I hope you must have realised by now that creating REST API on Node.js using Visual Studio is very simple. In next post we will consume this created REST service in different kind of clients. I hope you find this post useful. Thanks for reading.

Find Source Code on Github

Create a Router in Node.js using crossroads

Routers are very important in any web server. Primary function of a Router is to accept request and on basis of requested URL trigger desired process.

Consider a rough example in that client is requesting

http://abc.com/users/myprofile and there request may serve from URL http://abc.com/node/2 assuming user is stored in node with id 2.

image

In Node.js you can create router using many publicly available modules. Some of them are as follows,

  • Express
  • Director
  • Bouncy
  • Backbone
  • Crossroads

In this post let us create a router using Crossroads. To start with install crossroads module in application using npm crossroads or you may want to use mange modules in Visual Studio as well.

Once crossroads module is installed you need to load crossroads module in application.

image

You can add route in application using addRoute function. I have added route which takes two parameters.


crossroads.addRoute('/{type}/:id:',function(type,id){

 if(!id)
 {
 result = "Acess informtion about all " + type;
 return;
 }
 else
 {
 result = "Acess informtion about "+ type + "with id" +id ;
 return;
 }

 });

In above route

  • Type is parameter need to be passed to request server
  • Id is optional parameter to be passes to request server. Optional parameters should be enclosed with ::

Second parameter of addRoute is a callback function. In this callback you need to write logic to work with different requests with different parameters in request. As you see in above example we are constructing string on basis of requested URL.

If you write result in response then you will get output as below,

image

image

In first request we are passing only type (student) whereas in second request we are passing both type and optional id.

So when adding route you can have parameters in request as

image

If you want to add a route with REST segment then you can do that as follows,

clip_image002

Now on requesting server you will get id passed as optional REST segment.

image

Putting all together you can create a Router in Node.js application using crossroad as below,


var http = require('http');
var crossroads = require('crossroads');
var result ;
crossroads.addRoute('/{type}/:id*:',function(type,id){

 if(!id)
 {
 result = "Acess informtion about all " + type;
 return;
 }
 else
 {
 result = "Acess informtion about "+ type + "with id" +id ;
 return;
 }

 });

http.createServer(function(request,response){
 crossroads.parse(request.url) ;
 response.writeHead(200);
 response.write(result);
 request.on('end',function(){
 response.end("Req End");
 });

}).listen(8080,function(){

 console.log("server started");

 });

In above code apart from creating server we are parsing request URL as well using parse function

clip_image001

In this you can create a router. Off course you can use other modules to create router as well. When working with web applications router of express framework is very powerful. I hope you find this post useful. Thanks for reading.

Error: `doctype 5` is deprecated, you must now use `doctype html`: Node.js Express App bug solved

I am using Visual Studio to create Node.js application. I created a Node project by selecting Blank Express Application project template from JavaScript project type.

clip_image002

After creating project I pressed F5 to run application. On running application I got following error

clip_image003

Solving this error is very easy. From views folder in project open layout.jade. You will find below code

clip_image005

First line of code contains doctype 5. You need to replace it with doctype html

clip_image007

Now go ahead and press F5 to run application. You should not get above exception and in browser expected output you will get as below,

clip_image008

I hope you find this post useful. Thanks for reading.

Control Flow bindings in Knockout.js

You can control flow of element on the view using Control Flow bindings of Knockout.js. There are four Control Flow bindings

  • foreach binding
  • if binding
  • ifnot binding
  • with binding

Out of these four bindings foreach and if bindings are used very often.

foreach binding

foreach binding repeat same markup for number of times equivalent to number of elements in an array. It also binds each repeat of mark-up to corresponding item of the array.

image

Let us try to understand it with an example. Assume we have a ViewModel which contains observable array as one of the observable.


var viewModel =
 {
 students: ko.observableArray
 ([
 {name :"Dan W", subject : "JavaScript" },
 { name: "Glenn B", subject: "Node" },
 { name: "Pinal D", subject: "SQL" }
 ])
 }

ViewModel contains a property students which is an observable array. We can bind this on view to a table or lists elements.


<table>
 <thead>
 <tr>
 <th>Name</th>
 <th>Subject</th>
 </tr>
 </thead>
 <tbody data-bind="foreach: students">
 <tr>
 <td data-bind="text: name"></td>
 <td data-bind="text: subject"></td>
 </tr>
 </tbody>
 </table>

As you notice that on the table body we are performing foreach binding. So mark-up inside table body would be repeated 3 times in this case. Since number of elements in observable array is 3.

On running this application you will get table rendered with three rows as below,

image

Next let us consider one complex scenario in which we want to add and remove students. So let us go ahead an update view model with computed observable to add and remove items from observable array


function viewModel()
 {
 var self=this;
 self.students= ko.observableArray
 ([
 {name :"Dan W", subject : "JavaScript" },
 { name: "Glenn B", subject: "Node" },
 { name: "Pinal D", subject: "SQL" }
 ]);
 self.addStudent= function ()
 {
 self.students.push({ name: "dj", subject: "JavaScript" });
 };
 self.removeStudent= function ()
 {
 self.students.remove(this);
 }
 }

ko.applyBindings(new viewModel());

There is nothing much fancy in above ViewModel. We just added computed observables to add and remove students. Next we can bind that to a view contains unordered list as below


<h4>Students</h4>
 <ul data-bind="foreach: students">
 <li>Name at position <span data-bind="text: $index"></span>:
 <span data-bind="text: name"></span>
 <a href="#" data-bind="click: $parent.removeStudent">Remove</a>
 </li>
 </ul>
 <button data-bind="click: addStudent">Add</button>

On running application you will find that now you can add and remove student

image

You can use $index, $parent, $data with foreach binding as well. For example

  • You can read index of a particular element using $index.
  • You can read array element using $data. Not a particular element
  • You can read parent viewmodel or other properties of viewmodel using $parent

if binding

if binding allows whether a section of mark-up will appear or not. Unlikely visible binding if binding add or remove markup from the DOM. It performs following tasks,

  • Add or remove markup from the DOM
  • Make sure that data-bind attribute is having applied on the markup

Now let us take if binding in action. Let us say you have ViewModel as below


var viewModel =
 {
 show : ko.observable(false)
 }

ko.applyBindings(viewModel);

On View we can do binding as follows


<label><input type="checkbox" data-bind="checked: show" />Display Div</label>
<div data-bind="if: show">Visible/Hide using if binding </div>

As you notice that we are doing checked binding on input checkbox whereas performing if binding on div. If value of ViewModel property evaluates to non-false value then then div would be visible. Input is toggling value of show property.

Let us take another example in which we will learn that how if binding is useful in case of working with null. As you know if binding add or removes elements on the DOM having their data binding applied on that. Consider following ViewModel


function viewModel() {
 var self = this;
 self.students = ko.observableArray
 ([
 { name: "Dan W", subject: null },
 { name: "Glenn B", subject: { music: 'guitar' } },
 { name: "Pinal D", subject: { music: 'drum' } }
 ]);

};

Next we need to do if binding on the view,


<h4>Students</h4>
 <ul data-bind="foreach: students">
 <li>
 Student: <b data-bind="text: name"> </b>
 <div data-bind="if: subject">
 Subject: <b data-bind="text: subject.music"> </b>
 </div>
 </li>
</ul>

Above you see that we are applying if binding on div going to display subject. If binding add or remove on basis of non-falsie value. So for student subject value is set to null this div will not get created. If you try to achieve it using visible binding then for any student for which value if subject is set to null you will get subject.music throwing exception.

Ifnot binding

This is exactly the same as if binding. it only inverts the value passed to it.

So let us say you have ViewModel as below,


var viewModel =
 {
 display : ko.observable(false)
 }

and you bind this to a view as given below,


<div data-bind="ifnot: display">
 <h1>hello</h1>
 </div>

On running you will find div is added on the DOM even though display property in ViewModel is set to false. Because ifnot binding invert value of property in ViewModel.

When you create MVVM application using Knockout.js , control flow binding is very useful. You will use it very often and I hope you find this post useful in understanding control flow binding. Thanks for reading.

How to upload file in Node.js

In this post we will take a look on uploading a file on a web server created using Node.js. stream in Node.js makes this task super easy to upload files or for that matter working with any data transfer in between server and client.

To upload file we will work with two modules http and fs. So let us start with loading these two modules in application,


var http = require('http');
var fs = require('fs');

Once modules are loaded go ahead and create web server


http.createServer(function(request,response){

 }).listen(8080);

So far we are good and now we wish to perform following steps,

  1. Create a destination write stream. In this stream content of uploaded file will be written.
  2. We want to write back to client percentage of data being uploaded

First requirement can be done using pipe. pipe is event of stream in Node.js. And request is a readable stream. So we will use pipe event to write request to readable stream.


var destinationFile = fs.createWriteStream("destination.md");
 request.pipe(destinationFile);

Second requirement is to write back in response percentage of data uploaded. To do that first read total size if the file getting uploaded. That can be done by reading content-length (line no 1 in below code snippet). After that in data event of request we will update uploadedBytes which is in the beginning zero (line no 2). In data event of request we are calculating percentage and writing it back in the response.


var fileSize = request.headers['content-length'];
 var uploadedBytes = 0 ;

request.on('data',function(d){

 uploadedBytes += d.length;
 var p = (uploadedBytes/fileSize) * 100;
 response.write("Uploading " + parseInt(p)+ " %\n");

});

Putting all together your app should contain below code to upload a file and response back percentage uploaded.


var http = require('http');
var fs = require('fs');
 http.createServer(function(request,response){
 response.writeHead(200);
 var destinationFile = fs.createWriteStream("destination.md");
 request.pipe(destinationFile);

var fileSize = request.headers['content-length'];
 var uploadedBytes = 0 ;

request.on('data',function(d){

 uploadedBytes += d.length;
 var p = (uploadedBytes/fileSize) * 100;
 response.write("Uploading " + parseInt(p)+ " %\n");

});

request.on('end',function(){
 response.end("File Upload Complete");
 });

}).listen(8080,function(){

 console.log("server started");

 });

On command prompt start server as below,

clip_image002

Now let us use curl –upload-file to upload a file on server.

clip_image004

As you see that while file is being uploaded percentage of data uploaded is returned back to client. So in this way you can upload a file to server created using Node.js. I hope you find this post useful. Thanks for reading.

Create Echo Server in Node.js

Creating HTTP server in Node.js is very simple. In this post we will learn to create an echo server using Node.js.

Before we move ahead, let us understand what an echo server is. In echo server, client sends data to server and server returns back same data to server.

image

To create echo server, let us first create HTTP server. We need to export http module and then using createServer function HTTP server can be created.


var http = require('http');

http.createServer(function(request,response){

}).listen(8080);

To create echo server we will work with streams. In Node.js request and response are readable and writeable stream respectively.

image

Request readable stream got two events data and end. These events will be used to read data coming from client. These events can be attached to request stream as below,


request.on('data',function(message){

 });

 request.on('end',function(){

 response.end();
 });

Once we have created server and attached events to request, then we can write data from client back to client by writing to response as below,


request.on('data',function(message){

 response.write(message);

 });

Putting above discussion together full source code to create echo server is as follows,


var http = require('http');

http.createServer(function(request,response){

 response.writeHead(200);

request.on('data',function(message){

 response.write(message);

 });

 request.on('end',function(){

 response.end();
 });
 }).listen(8080);

So you can run application on command prompt using node

clip_image001

When web server is running then using curl post data to server as below. You will get response back as below,

clip_image002

In above approach we used data and end event to echo data back to client. Node.js provides another way to write back requested data to response using pipe. You can create echo server using pipe as below,


var http = require('http');

http.createServer(function(request,response){

 response.writeHead(200);
 request.pipe(response);

}).listen(8080);


Above application will send data back to client. In these two ways you can create echo server in Node.js. I hope you find this post useful. Thanks for reading.