Incremental Loading of Data using Windows Azure Mobile Services


When your data is in the cloud you should only download information that a user is actually looking at.  In the case where you have thousands of items and you want to give the ability to scroll through them you should only fetch the data that the user will be viewing (yes, I know that is a horrible UI design – another blog opportunity).  Chances are they will not make it through the whole list.

Our XAML controls support being backed by an Incremental loading scheme.  I will show how to leverage this by modifying one of our existing samples and use Windows Azure Mobile Services as a backend (because it is really cool)!

Prep work:

Add a new Windows Azure Mobile Service for the project and configure it

  • Create a new Mobile Service
  • Choose the ‘Connect an existing Windows Store app’ option from the dashboard of your new project

image

  • Hit the ‘Create Item table’ button and we will use this for our data (note: this is a different table and will be a different schema than the TodoItem table that you would use for the ‘Create a new Windows Store app’ option).
  • Keep this page up (or return to it later) so we can copy the code listed into our project.  You will cut and paste the information from step two here in the following instructions

Modify the existing sample to use our new Windows Azure Mobile Service

  • Build and run the existing sample to ensure there are no problems, try ‘Scenario 8’ as this is the section we will modify.
  • Follow the instructions from the Mobile Service portal to ‘Connect an existing Windows Store app’ from Step 2.
    • In your Visual Studio project, add a reference to the “Windows Azure Mobile Services Client” extension (did you install the SDK like I told you?).

image

      • Add “using Microsoft.WindowsAzure.MobileServices;“, to your App.xaml.cs file, then copy and paste the following code into your App.xaml.cs file inside the App from the portal page you left open above into the class definition like this:

image

  • Build to check for any errors

 

Modify Scenario 8 to use our new Mobile Service

‘Scenario 8’ already uses an incremental loading class so we will modify that scenario and show how easy it is to use Cloud Storage instead of static data.  The Mobile Services portal has some instructions on how to connect and existing app to the data.

Here is where we will deviate slightly from the instructions in your Mobile Service portal.  We created a table called ‘Item’ but the columns do not match what we want for this sample code.  Open Scenario8.xaml and look at the binding for the list view.  You will see the data is bound to ‘Name’ and ‘Organization’.  We could use the ‘Text’ field in our Mobile Service ‘Item’ table and remap it to either of these fields in the XAML and create a new column dynamically, but lets create and modify a new table instead.

  • Back to your Mobile Service portal.
  • Click on your newly created Mobile Service and hit the DATA tab.  You should see the ‘Item’ table we created earlier.
  • Delete the Item table by hitting the DELETE icon at the bottom of the page
  • Then hit the CREATE icon right next to the DELETE icon and create a new table called ‘Employee’

image

  • Click on the Employee table after you have created it and you will see it has only one column which is the id column (we will add data with the required columns later).

image

 

Now lets modify some code we need to attach to our data source

There are three files we will be modifying.  The first file is Scenario8.xaml.cs.

  • Open this file and find the constructor for GeneratorIncrementalLoadingClass<Employee>.  This constructor takes a generator function that pre-populates data.  We will be using a data source so lets remove all that garbage!  You will see below where I added the new constructor that we will define and commented out the old one.  Also, mark the function async and add and await for a new function we will add called initAsync():

image

 

Now we will modify the logic for the incremental loading behavior we desire and add the new constructor and initAsync method.  This file: GeneratorIncrementalLoadingClass.cs implements the interface we are using and has the old constructor.  Open that file and make the following changes:

  • Remove the old constructor and code   public GeneratorIncrementalLoadingClass(uint maxCount, Func<int, T> generator)
  • Add the new constructor  public GeneratorIncrementalLoadingClass(){ }
  • Remove Func<int, T> _generator; (it is in the State region at the bottom of the file)
  • In LoadMoreItemsOverrideAsync, Delete the  code under ’//Wait for work’ and ‘//This code simply generates’.
  • Now your code should look like this (we will add only one line of code to get the table data later):

    
image

 

  • Add a reference to using Microsoft.WindowsAzure.MobileServices;
  • Define a private member that references the employees table from the Mobile Service (note that this is using the existing class definition we already had in our code… Pretty cool eh?):

image

 

  • Now we will define the ‘initAsync’ function.  This function is used to get and set the number of rows in the data source to the variable _maxCount.

image

  • Finally we need to fetch the data from the employee table and return the values.  Modify LoadMoreItemsOverrideAsync as pictured (This is only one line of code we added!).

image

The next and last code file we need to modify is Employee.cs.

  • Our table will have an Id member so we simply need to add that to the existing class definition: Modify Employee to have an id:  public int Id { get; set; }

image

The final change is to the Manifest.  We simply need to add ‘Internet’ so when we access the Mobile Service the call is allowed out.

image

 

Now compile and run the application.  Go to Scenario8 and you should have no data but no errors!

Generate sample data

Now we need to generate some sample data for our app to show how it is incrementally fetching data.  We will use the scheduler in our Mobile Service to do that.

  • Click on the ‘SCHEDULER’ item and choose ‘CREATE A SCHEDULED JOB’

image

  • Use ‘prepopulate’ for the name and chose the ‘On demand’ radio button

image

 

  • Add this code to insert 1000 records (thanks to Paul Batum for this script)

function prepopulate() {
    var employeeTable = tables.getTable(‘Employee’);
    console.log(“Running ‘PrePopulateTable’ job.”);
   
    var recordsToInsert = 1000;
    var batchSize = 10;
    var totalCount = 0;
    var errorCount = 0;
 
    insertItems();
 
    function insertItems() {
        var batchCompletedCount = 0;
 
        var insertComplete = function() {
            batchCompletedCount++;
            totalCount++;
            if(batchCompletedCount == batchSize) {                       
                if(totalCount < recordsToInsert) {
                    insertItems();
                } else {
                    console.log(“Job ‘PrePopulateTable’ complete. There were %d errors.”, errorCount);
                }
            }
        };
 
        var errorHandler = function(err) {
            errorCount++;
            console.warn(“Ignoring insert failure as part of batch.”, err);
            insertComplete();
        }
 
        for(var i = 0; i < batchSize; i++) {          
            var num = totalCount + i;
            var item = { Name: “Name” + num, Organization: “Organization” + num };
            employeeTable.insert(item, {
                success: insertComplete,
                error: errorHandler
            });
        }
    }
}

Some notes on this script:

I chose to use the same data as the original sample which results in ‘Name1’ and ‘Organization1’ etc… Feel free to get more creative.

This script avoids an issue that you could hit if you iterate over a simple loop and insert the items.  Since the insert is asynchronous you could run out of connections to the SQL backend (this is limited in our scheduler on purpose) and hang your service.  So… use this script which waits for completion before resuming the insert (Paul developed this script for me).

Note that I am inserting ‘Name’ and ‘Organization’ columns and this happens automatically for me thanks to the Dynamic Schema ability of Mobile Services (you can turn that off BTW).

  • ‘Save’ the script
  • Hit ‘Run Once’ and after you get notification that the job has submitted
  • Go to the ‘LOGS’ area of your Dashboard and refresh the page periodically until you see the two messages shown (which the script will write to the log).

image

  • The sample data has be populated!
  • Go to the ‘DATA’ tab and see the new records and columns added

image

 

 

See the data in action!

Now you should be able to Run the app (or hit the refresh button if the app is still up) and see the records incrementally loading!  Note how the incremental loading only loads what the user is scrolling to (note the weird scroll bar behavior too since the control does not ask for the total count).

Summary

You saw how with very few lines of code and very little effort we could add a Cloud based data source using Windows Azure Mobile Services to our existing incremental loading sample.  I leave details like updating and records to you but as you learn more about Windows Azure Mobile Services and go through the tutorials you will see how easy that is.  Again, loading thousands of items in a list box probably is not the best design for accessing data, however you can see how even loading a few hundred can be more efficient using incremental loading.  Attached is a zip that has the code I modified for this example.

Good luck programming with Windows Azure Mobile Services and Windows Store apps!  Be sure to post any questions or comments as you play with these technologies up on the forums (where I hang out a lot lately): Windows Store apps and Windows Azure Mobile Services

Special thanks to Matt Small and Paul Batum for helping me overcome issues when developing this Blog!  Don’t forget to follow the Windows Store support team on Twitter @wsdevsol.

XAML data binding sample Incremental.zip

Comments (2)

  1. Sal says:

    What do you mean by this line? What aspect is the horrible UI design?

    In the case where you have thousands of items and you want to give the ability to scroll through them you should only fetch the data that the user will be viewing (yes, I know that is a horrible UI design – another blog opportunity).  Chances are they will not make it through the whole list.

  2. Jeff Sanders says:

    Hi Sal,

    Sheesh I missed your question some how… Sorry!

    I meant that trying to navigate through thousands of items in a list view is terrible.  You give up after the first couple of hundred.  You should provide a search or hierarchy to navigate a lot of items.

    Jeff

Skip to main content