OData Code Snippets

This topic provides some snippets to help you get up and running quickly when using the datajs OData support.

Reading and displaying data
The following snippet shows how to read a list of category names from the Northwind service, using jQuery to add them to an element with ID 'target-element-id'. Because the service supports JSONP, the default network library uses it even though the document comes from a different domain.

OData.read( 
  "http://services.odata.org/Northwind/Northwind.svc/Categories", 
  function (data) { 
    var html = ""; 
    $.each(data.results, function(l) { html += "<div>" + l.CategoryName + "</div>"; }); 
    $(html).appendTo($("#target-element-id")); 
  } 
);

Reading paginated data
The following snippet shows how to read a collection that the server sends down in pages, and concatenating all results into a single array.

var arr = [];
var collectionUrl = "OData-url";

function readMoreData(url) {
  OData.read(url, function (data) {
    arr = arr.concat(data.results);
    if (data.__next) {
      readMoreData(data.__next);
    } else {
      alert("Done!");
    }
  });
}

readMoreData(collectionUrl);

Adding data
The following snippet shows how to add a new customer to an OData service that exposes a Customers resource set with Name, CustomerCategory and ID properties.

OData.request( 
  { requestUri: "/customer-service/Customers", 
    method: "POST", 
    data: { Name: "customer name", CustomerCategory: 123 } }, 
  function (insertedItem) { 
    $("<div>inserted customer ID: " + insertedItem.ID + "</div>").appendTo($("#target-element-id")); 
  } 
);

Adding data in batches
The following snippet shows how to add and cross-reference a Customer and an Order. Note that the first request includes a header for "Content-ID", and the second request references the newly added customer as "$1".

// The request will be a batch of read and change operations.
// The changes all go together in a single __changeRequests.
var requestData = { __batchRequests: [ { __changeRequests: [
    { requestUri: "Customers", method: "POST", headers: { "Content-ID": "1" }, data: { 
        CustomerID: 400, CustomerName: "John"
    }  },
    { requestUri: "Orders", method: "POST", data: { 
        OrderID: 400, Total: "99.99",
        Customer: { __metadata: { uri: "$1" } }
    } }
] } ] };           

OData.request({
    requestUri: "/ScratchService.svc/$batch",
    method: "POST",
    data: requestData
}, function (data) {
    // Look for errors within the responses.
    var errorsFound = false;
    for (var i = 0; i < data.__batchResponses.length; i++) {
        var batchResponse = data.__batchResponses[i];
        for (var j = 0; j < batchResponse.__changeResponses.length; j++) {
            var changeResponse = batchResponse.__changeResponses[j];
            if (changeResponse.message) {
                errorsFound = true;
            }
        }
    }

    // Display whether any errors were found, and a JSON-ified payload.
    alert("Result (errors found=" + errorsFound + "):\r\n" + window.JSON.stringify(data));
}, function (err) {
    alert(err.message);
}, OData.batchHandler);

Previous Topic: Using OData
Next Topic: OData Networking

Last edited Aug 18, 2011 at 1:29 AM by dazhang, version 7

Comments

Michahell Feb 21, 2013 at 7:27 PM 
I am working on a localhosted MAMP server, and i get a crossdomain error. shouldn't happen with JSONP though. what's going on? does 'Northwind' still support JSONP?

ondrejsv Jan 5, 2013 at 11:58 AM 
There's an error in the first sample - the first parameter of the callback of the jQuery each function is the index of the current element. It should read:
$.each(data.results, function(ix, l) { html += "<div>" + l.CategoryName + "</div>"; });

marcelolr Jul 10, 2011 at 6:16 AM 
@hongtaoc, yes, you can add a function parameter with the results, and keep an array scoped to the invocation.

function readAllData(collectionUrl, callback) {
var arr = [];

function readMoreData(url) {
OData.read(url, function (data) {
arr = arr.concat(data.results);
if (data.__next) {
readMoreData(data.__next);
} else {
callback(arr);
}
});
}

readMoreData(collectionUrl);
};


You could also add an extra argument to handle failures (instead, errors in this sample go to OData.defaultErrorHandler).

hongtaoc Jul 9, 2011 at 4:43 PM 
thanks for the example, a few questions about the example, the current read more function does not have a callback function, which I cannot catch the complete event. should I add an function parameter? 2. If I have more than 1 read more calls on the page, the global result array will cause problem. should I also create a parameter for it?

marcelolr Jun 28, 2011 at 7:09 PM 
The data will have a __next member in this case. I've added a "Reading paginated data" snippet to demonstrate.

hongtaoc Jun 28, 2011 at 6:10 AM 
How to handle service page size with continuation token?