How to build a Simple OData-based ajax application

Follow this tutorial to create your first HTML5 five application with JayData as a convenient client library for an oData service. You will need Visual Studio 2010 or Visual Studio 11 to complete this walkthrough, all editions are supported. We assume that you also have SQL Server CE 4.0 support installed on you developer box.

 

 

Create web application

 

Create an empty web application

image

 

From %Program Files%\Microsoft SQL Server Compact Edition\v4.0\Samples drop Northwind.sdf into your App_Data folder. (You might have to create it with Add / Add ASP.NET Folder)

 

image

 

 

Add an ADO.NET EDMX model definition.

 

image

 

 

 

Use the database first approach to have a Northwind data context populated with entity definitions and

relations:

 

 

imageimage

 

 

Now publish your Entity data model with as a WCF Data Service.

 

image

 

 

In the Northwind.svc code allow read/write access to every entity sets

 

using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;

namespace NWind
{
    public class Northwind : DataService<NorthwindEntities>
    {
        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
    }
}

 

 

You are done with the oData endpoint. Test it by directing your browser to the Northwind.svc file:

 

image

 

Now that you have a working oData service, let’s get JayData. You can download it from http://jaydata.org/download or simple installing it with nuget. Open the package management console and

 

PM> Install-Package JayData

 

 

image

 

 

You’ll see that a command line utility is also copied into the web folder. With that you can create a JayData client context from any oData metadata document.

 

C:\JayDataDemo\NWind\NWind>JaySvcUtil.exe -m http://localhost:64635/Northwind.svc/$metadata 
–n northwind -o northwind.js

 

image

 

 

A northwind.js file is also generated what you have to include in your HTML page along with JayData.js and jQyuery

 

 

image

 

 

Now let’s the fun really begin:

 

Getting a list of categories:

 

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript" src="/scripts/jquery-1.7.1.min.js"></script>
    <script type="text/javascript" src="/scripts/datajs-1.0.3.js"></script>
    <script type="text/javascript" src="/scripts/jaydata.js"></script>
    <script type="text/javascript" src="/scripts/jaydataproviders/oDataProvider.js"></script>
    <script type="text/javascript" src="northwind.js"></script>
    <script>
        var nwcontext = new northwind.NorthwindEntities({
            name: 'oData',
            oDataServiceHost: 'http://localhost:64635/Northwind.svc'
        });

        function createItemLI(name, id, css) {
            var li = $('<li></li>').append(name).addClass(css).data('id', id);
            return li;
        }

        $(function () {
            nwcontext.Categories.toArray(function (categories) {
                categories.forEach(function (category) {
                    $('#categories').append(
                        createItemLI(category.Category_Name, category.Category_ID, 'category'));
                });
            });
        });
    </script>
</head>
<body>
    <ul id="categories">
    </ul>
</body>

 

and voila:

image

 

It works! But. 115KB for exactly 8 names seems a bit too much network traffic. The reason is that category has a picture that is in the response as well. This can be an overkill on mobiles and if we are using a cloud storage without a flat-rate plan, this is clearly an expensive waste of ammo. This is why projection is invented for: let’s shape the results to better reflect to out needs. We only need an Id and a Name.

 

With the code a bit reworked…

        $(function () {
            nwcontext.Categories
                .map(function (category) { return {
                        Name: category.Category_Name,
                        Id: category.Category_ID
                }})
                .toArray(function (categories) {
                categories.forEach(function (category) {
                    $('#categories').append(
                        createItemLI(category.Name, category.Id, 'category'));
                });
            });
        });

 

…we can achieve significant performance improvement, just by letting the server know (and also using a server that cares) what I really need.

image

 

 

Our last step will be to list products to categories. The whole “application” thus will look like:

 

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript" src="/scripts/jquery-1.7.1.min.js"></script>
    <script type="text/javascript" src="/scripts/JayData.js"></script>
    <script type="text/javascript" src="/northwind.js"></script>
    <script>
        var nwcontext = new northwind.NorthwindEntities({
            name: 'oData',
            oDataServiceHost: 'http://localhost:64635/Northwind.svc'
        });

        function createItemLI(name, id, css) {
            var li = $('<li></li>').append(name).addClass(css).data('id', id);
            return li;
        }

        $(function () {
            nwcontext.Categories
                .map(function (category) { return {
                        Name: category.Category_Name,
                        Id: category.Category_ID
                }})
                .toArray(function (categories) {
                categories.forEach(function (category) {
                    $('#categories').append(
                        createItemLI(category.Name, category.Id, 'category'));
                });
            });
        });
        $('.category').live("click", function () {
            $('#products').html('');
            nwcontext.Products
                .filter(function (product) {
                    return product.Category.Category_ID == this.id
                }, { id: $(this).data('id') })
                .orderBy("it.Category.Category_Name")
                .map(function (product) {
                    return { Name: product.Product_Name, Id: product.Product_ID }
                })
                .forEach(function (product) {
                    var item = createItemLI(product.Name, product.Id, 'product');
                    $('#products').append(item);
                });
        });

    </script>
</head>
<body>
    <ul id="categories">        
    </ul>
    <ul id="products">
    </ul>
</body>
</html>


 

 

image

 

In the next article I’ll show how to create or modify existing data.

Share this