Windows Store App Development Series: Part 20–WinJS Promise Object Join

Hello reader

As we know fundamentals of WinJS Promise object, lets explore it further and understand how to make a asynchronous call to multiple web services in parallel. If you’re not familiar with WinJS promise object and the useful functions (xhr, done, then) it provides, I strongly recommend you to go through the below mentioned articles of this series before reading further.

Promise.join

WinJs Promise object provides a join method which makes it possible to combine multiple WinJS promise objects, which internally can call to different web services asynchronously. It returns a WinJS Promise object, when all the values / child promises are fulfilled. The parameters passed to promise.join method can be a constant value known at compile time, value returned from some function or a WinJS promise object itself. Below is the syntax of join method

promise.join(values).done( /* Your success and error handlers */ );

Since the promise.join method can have different types of parameters, I will explain two scenarios in this article.

  • WinJS.Promise.join with WinJS.Promise.timeout function
  • WinJS.Promise.join with WinJS.Promise.xhr function

WinJS.Promise.join with WinJS.Promise.timeout function

  1. Create a Windows Store App using JavaScript – Blank App template.
  2. In default.html file, add below defined code. It contains placeholder Div elements to display name and website information.
  3. <div id="ContainerDiv">
        <div id="NameOutputDiv"></div>
        <div id="WebsiteOutputDiv"></div>
    </div>
    
  4. In default.js file, add below defined code under app.onactivated event handler. WinJS.Promise.timeout function creates a promise object after the specified time interval. In this case, we are creating two such WinJS promises and adding it to promises array. WinJs.Promise.join method then combines these promises into one call. When both the promises completes its execution, we are setting few CSS properties of ContainerDiv element. Note, I have used JavaScript setTimeout function to add some delay while drawing the border.
    var nameOutputDiv = document.getElementById('NameOutputDiv');
    var websiteOutputDiv = document.getElementById('WebsiteOutputDiv');
    
    var promises = [];
    promises[0] = WinJS.Promise.timeout(3000)
    			   .then(function () {
    				   nameOutputDiv.textContent = "Prasad Honrao";
    			   });
    
    promises[1] = WinJS.Promise.timeout(6000)
    			   .then(function () {
    				   websiteOutputDiv.textContent = "http://PrasadHonrao.com";
    			   });
    
    WinJS.Promise.join(promises).done(
    	function () {
    		setTimeout(function () {
    			var containerDiv = document.getElementById('ContainerDiv');
    			containerDiv.style.border = "2px solid white";
    			containerDiv.style.borderRadius = "10px";
    		}, 3000);
    	}
    );
    
  5. Run the code and and you should get output as shown below. Note, I have modified default.css file to set the appearance of the DIV elements.
    01. WinJS Promise Object Join Scenario 1

    01. WinJS Promise Object Join Scenario 1

WinJS.Promise.join with WinJS.Promise.xhr function

  1. Create a Windows Store App using JavaScript – Blank App template.
  2. Add below mentioned code in default.html file. We have defined two WinJS.UI.ListView controls which will display Customer and Product information respectively.
    <body>
        <div id="CustomerDataTemplate" data-win-control="WinJS.Binding.Template">
            <div class="CustomerItemContainer" data-win-bind="innerText:ContactName"></div>
        </div>
    
        <div id="ProductDataTemplate" data-win-control="WinJS.Binding.Template">
            <div class="ProductItemContainer">
                <div data-win-bind="innerText:ProductName"></div>
                <div data-win-bind="innerText:UnitPrice"></div>
            </div>
        </div>
    
        <div id="ContainerDiv">
            <div id="CustomerListView"
                data-win-control="WinJS.UI.ListView"
                data-win-options="{itemTemplate: select('#CustomerDataTemplate')}">
            </div>
            <div id="ProductListView"
                data-win-control="WinJS.UI.ListView"
                data-win-options="{itemTemplate: select('#ProductDataTemplate')}">
            </div>
        </div>
    </body>
    
  3. In default.js file, add below defined code under app.onactivated event handler.
    var customerPromise = WinJS.xhr(
    		{ url: "http://services.odata.org/V3/Northwind/Northwind.svc/Customers" }
    	    );
    
    var productPromise = WinJS.xhr(
    		{ url: "http://services.odata.org/V3/Northwind/Northwind.svc/Products" }
    	     );
    
    var promises = { customer: customerPromise , product : productPromise } ;
    
    WinJS.Promise.join(promises).done(
    
    	function complete(xhr) {
         	    var customerResult = xhr.customer.responseXML;
    	    var items = customerResult.querySelectorAll("entry");
    
    	    for (var ctr = 0; ctr < items.length; ctr++) {
    		var customer = {};
    		customer.ContactName = items[ctr].querySelector("ContactName").textContent;
    			customerList.push(customer);
    		}
    
    	    var customerDataList = new WinJS.Binding.List(customerList);
    	    var customerListView = document.getElementById('CustomerListView').winControl;
    	    customerListView.itemDataSource = customerDataList.dataSource;
                
                // Extract product information similarly.
    	}
    );
    
  4. Similar to earlier example, we have defined two WinJS Promise objects using WinJS.xhr functions. The customerPromise object retrieves the data from Customer entity set of Northwind OData service, and productPromise object gets it from Product entity set.
  5. Instead of array, this time we have added both customerPromise and productPromise objects into a custom object called promises. This helps you to extract the xhr information result using object name rather than using array index like 0, 1.
  6. WinJS.Promise.join function then takes promises object as parameter, which in turn calls both the services in parallel. Once both the promises returns the value, we get the result of both the service call complete function.
    var productResult = xhr.product.responseXML;
    var customerResult = xhr.customer.responseXML;
    
  7. Next, we are simply iterating over XML responses and persisting it into local variables customerList and productList, which help us to create a WinJS.Binding.List object and bind it to WinJS ListView defined in HTML view.
    var productResult = xhr.product.responseXML;
    var items = productResult.querySelectorAll("entry");
    
    for (var ctr = 0; ctr < items.length; ctr++) {
        var product = {};
        product.ProductName = items[ctr].querySelector("ProductName").textContent;
        product.UnitPrice = items[ctr].querySelector("UnitPrice").textContent;
        productList.push(product);
    }
    
    var productDataList = new WinJS.Binding.List(productList);
    var productListView = document.getElementById('ProductListView').winControl;
    productListView.itemDataSource = productDataList.dataSource;
    
  8. That’s all. Modify the CSS as per your need and run the application. You should get output as shown below.
    02. WinJS Promise Object Join Scenario 2

    02. WinJS Promise Object Join Scenario 2

Summary

In this article, we explored WinJS Promise object further and discussed WinJS.Promise.join function to combine multiple WinJS Promise objects. We also discussed how to use WinJS.Promise.timeout function to create a WinJS Promise object after specific time interval. We have seen different types of parameter passing to WinJS.Promise.join method.

I hope this article was useful to you.

Download Source Code

Complete source code of this series is available on GitHub.

4 Comments

  1. Nicollet Fabien · April 16, 2014 Reply

    Great examples, thanks for this article, I have been able to merge two XHR results into the WinJS UI SearchBox suggestion handler that only take a promise

    Thanks!
    Fabien

  2. Sanjeev · March 4, 2015 Reply

    Great article. Saved my day. Thanks.

Leave a Reply