Developing a responsive, interactive web application is tedious work before a decade. But today, it is absolutely possible using asynchronous programming with JavaScript and modern web design techniques.
Asynchronous programming is becoming more important to have interactive and responsive web applications and sites. Asynchronous programming can be challenging to work with JavaScript since they have nested callbacks.
JavaScript libraries like jQuery have added an abstraction called deferreds to make the asynchronous programming easy with JavaScript. With this, developers can use deferreds in any browser for the responsiveness of the web application.
Promises
Promises are objects that represent the pending result of an asynchronous operation. This object will hold the information about the status of the async operation and will notify us when the async operation succeeds or fails.
States of Promise
A promise has three states called unfulfilled, fulfilled and failed.
- unfulfilled: initial state of a promise.
- fulfilled: returned the result, success state
- failed: returned with exception, failed state.
Promises provide the way to work with asynchronous events. Let us see how Promises are used in LightSwitch HTML Client with WinJS.
Promise in WinJS
A WinJS Promise provides a mechanism to schedule work to be done on a value that has not yet been computed. It is an abstraction for managing interactions with asynchronous APIs.
A promise can be created as shown below:
var promise = new WinJS.Promise(init, onCancel);
The WinJS.Promise class accepts two parameters init and onCencel respectively. The init parameter is a function that accepts the three parameters completed, error and progress respectively. The onCancel function will be executed when the promise is cancelled.
The Promise Class is defined in the WinJS namespace as shown in the preceding figure.
It is exposed as Promise in the WinJS namespace.
WinJS Promise in LightSwitch HTML Client
The WinJS Promise class is initiated and exposed as msls_promiseOperation in msls.js.
To query the DB, the LightSwitch Core framework uses the msls_promiseOperation instance as shown below.
Inside the msls.js's executeQuery function, a msls_promiseOperation is used to handle the API calls to query the DB.
Note that executeQuery returns the promise since it allows the chaining.
When the application is loading, the LightSwitch framework core makes a call to executeQuery with a WinJS Promise to get the data from Server with the requestUrl /ApplicationData.svc.
Let us have an example to demonstrate the usage of WinJS Promise.
We will use the example project from my last article. Add an extra table to the project with name the "NorthWindOrders".
Add a property called "Name" to display the Order name from the northwind ODATA service.
Add a screen to display the orders from the NorthWind OData service.
Add a command button to import all the orders from the Northwind Service as shown above.
To write the code to get the orders from Service, Edit the execute code as shown above.
In the preceding figure, we have added the header part for the Ajax call since the NorthWind OData Service will return the result as XML by default.
// northwind url
var northwind = "http://services.odata.org/Northwind/Northwind.svc/Orders?$top=10";
var headers = {
accept: "application/json;q=0.8, application/json;odata=fullmetadata;q=0.7, application/atomsvc+xml;q=0.5, */*;q=0.1"
};
We are using msls.js's promiseOperation function to make the Ajax call. The promiseOperation wraps the getNorthWindOrders functions and injects the promise operation as a parameter.
// This function will be wrapped in a Promise object
function getNorthWindOrders(operation) {
$.ajax({
type: 'get',
headers: headers,
url: northwind,
success: operation.code(function ajaxSuccess(result) {
operation.complete(result);
}),
error: operation.code(function (result) {
operation.complete(result);
})
});
operation.interleave();
}
};
Since promiseOperation returns the promise, we are chaining the msls.promiseOperation method with the function with two callbacks to be executed once the promise operation is completed.
// Using a Promise object we can call the getNorthWindOrders function
msls.promiseOperation(getNorthWindOrders).then(function promiseSuccess(result) {
for (var i = 0, len = result.value.length; i < len; i++) {
var importedOrder = screen.NorthWindOrders.addNew();
importedOrder.Name = result.value[i].CustomerID + ' ships to ' + result.value[i].ShipCountry;
}
}, function promiseFailure(result) {
});
In the Ajax call, if it is successful, we are completing the operation with a complete function of operation. In a successful promise operation, we are adding NorthWindOrders.
This is how to use WinJS Promise for the Ajax calls.
Output