- Boiling jQuery down to the essentials (technique)
- Using jQuery AJAX with a HTTP handler (technique)
- Returning JSON from a HTTP handler (technique)
- Enable Intellisense for Client OM and jQuery (tip)
- Useful tools when building AJAX applications (tip)
- Migrating existing applications to jQuery/AJAX
Some key things to consider if you’re looking at the Client OM for the first time:
- Async programming model – the basic sequence of steps is to get a reference to the ClientContext (similar to SPContext), read/update data, then call ClientContext.ExecuteQueryAsync(). This last method is what triggers things to actually happen (i.e. the request to the server), and you pass 2 ‘callback’ method names to run on success/failure.
- This is similar to other disconnected programming, and also jQuery’s AJAX methods which we’ll look at next article
- Fetching some data (title of current web)
- Fetching items from a list/library
Something we may definitely want to do at some point with the Client OM is retrieve the items in a list or library. The same pattern is used but we effectively navigate down the SharePoint hierarchy to the list in question, and then run a CAML query (no LINQ in the Client OM). Notice that there is no ‘indexer’ property to get a single list on the client – we call .get_lists() to return all the lists in the web, then call .getByTitle(‘My list name’) on the resulting collection – a good example of the occasional difference compared to the server-side object model. In the callback, we have a collection we can enumerate through, with each item having a property named ‘FileLeafRef’ (which you may have seen previously in CAML queries) for the filename:
A couple of other things to notice about this example:
- I’m using the slightly more complex syntax of Function.createDelegate(this, myFunctionName) with ClientContext.ExecuteQueryAsync(). The MSDN samples use this syntax, but I understand it’s not strictly necessary and does clutter the code somewhat. Certainly my testing shows that the code still works and the args/sender variables are still passed to the callbacks, which is something I’d wondered about.
- The SP.CamlQuery.createAllItemsQuery() method provides a handy shortcut in the Client OM to creating a CAML query for all the items in the list.
- Fetching list items with query (type-ahead)
Let’s turn the last example into something more useful and cool – a list of items on the page which dynamically filters as you type the filename into a box. This is an extremely useful pattern to understand, and is essentially the same mechanism for many cool things you may have seen e.g. Google Instant Search. In fact we only need to change a couple of things to enable this – instead of a button click event we respond to the textbox’s keyup event, and instead of a CAML query which returns all items, we need a CONTAINS query which drops the value from the text box into the clause:
- Add new list items to a list
Performance/writing efficient Client OM code
So what kind of things make a difference? Well, there are two main ones:
- Calling .Load() on objects where it’s not needed
- Returning more properties (e.g. fields for a list item) than are needed
For the first, consider that on our way to get some lists items we can write some code to get a list in two ways:
In both cases, we would later have a ctx.load(listItems) line. However in the second case, the JSON for the web, lists and target list are not sent over the wire – only the JSON for actual list items. This will cut down the data significantly (I’ll show numbers later).
For the second (returning more properties for an object than are needed), this is obviously analagous to a SQL SELECT * vs SELECT [mySingleColumn] query. We haven’t yet shown how to filter the properties returned, but it’s very important – first let’s look at what we have been doing so far:
When I was testing the different code patterns, this is what I saw – note I was only testing on a query which returned 8 items:
My observations from this are:
- None of these numbers are scary, but then again we’re talking a mere 8 items here! However, the proportions are very interesting, and if (say) 100 items were being returned then clearly the amount of data would mean big benefits from writing code the right way
- Proportions - the largest data set is 15 times the size of the smallest
- The automatic compression in the Client OM saves your ass. The ‘Uncompressed size’ column is technically irrelevant as data is always compressed over the wire – however at some point it exists decompressed, and we can see how big the data really is here (61KB for 8 list items would be very bad indeed).
So to reiterate, only call ClientContext.Load() on objects you need to and be sure to restrict the properties returned. Hopefully though you can see that the Client OM and jQuery are great tools for building SharePoint apps which aren’t postback hell.
Next time: Using jQuery AJAX with a HTTP handler