Working with SharePoint Lists in LiquidSilver

In this post, I’ll cover some common operations on SharePoint lists which you can simplify with LiquidSilver. For this purpose, I continue using the Actors list we created earlier.

1. Clearing all items in a list

One day, Katie — one of Tom’s client — came by and asked whether she could empty the Actors list in one go instead of deleting each item individually, which was, of course, pretty tedious. Wanting to impress this cute woman, Tom said promptly that it was a piece of cake, he just needed an hour or two to provide this functionality.

Tom decided to customize the toolbar to include a Clear All Items command in the menu. He didn’t know how to do it yet, so he asked his good friend, Google, that led him to a helpful blog post. Tom was successful and happy to create the shiny new menu under an hour, then he started to code the implementation.

Being a smart codebender, Tom knew he just needed to find the Empty() or ClearItems() method of the particular SPList object. Unfortunately, they didn’t exist. Tom could only see a Delete() method which he knew that it would delete the list, not the items. Then he typed SPList.Items.Clear() instead. Nice try, but it also didn’t exist. “Well, let’s do it in old-fashioned way!” Tom said to himself. He quickly wrote and compiled this piece of code in the editor:

foreach (SPListItem item in list.Items)
{
  item.Delete();
}

Too bad when he ran it, it threw an exception saying: “Collection was modified; enumeration operation may not execute.” He was smart enough to figure out how this happened and quickly rewrote the code as follow:

var items = list.Items.Cast<SPListItem>().ToList();
var count = items.Count;
for (int i = count - 1; i >=0; i--)
{
  items[i].Delete();
}

Thanks to LINQ, he could fix it with only two more lines. Almost two hours had passed when he heard someone approaching, this must be Katie. Just in time when Katie asked him about her little request, Tom finished with his testing and packaging. With a big smile he said that everything was fine and he was ready to deliver the feature right away. Katie looked happy and she went back to her workstation to try the feature.

While Tom was packing to leave for the day, his phone rang, it was Katie. Excitedly he picked up the phone, little did he know that Katie was upset because the deletion process was so slow it crashed the server. Tom asked her, how many records she was trying to delete. She said there were several thousands of records.

Tom realized that his approach was sub-optimal. He already knew from the SharePoint coding best practice guideline that accessing the Items property should be avoided. Furthermore, to access more than 2000 items, pagination should be used. Tom also knew that to process a lot of items at once, it was better to use the ProcessBatchData method than deleting the items one at a time. But the batch processing requires a proper CAML query to be constructed and it is ugly. He ended up spending a couple more hours to implement all these things.

Tom was kind enough, though, that he didn’t want others to go through this. He decided to put his implementation in a way to be usable by everyone else and push the code to the open source LiquidSilver SharePoint Framework. So now, we can use the following code to clear all items from a list easily and efficiently:

bool continueOnError = true;
new HgList(web.Lists["list name"]).ClearItems(continueOnError);

2. Batch updating items in a list

The ProcessBatchData method is not only useful for deleting multiple items in a batch. An MSDN article shows that it can be used for batch updating list items, too. It is a faster and preferred way to update multiple items in a list.

Unfortunately, once again you have to deal with the cryptic CAML query as shown in the article. While he was at it, Tom had the chance to create a nice wrapper function, though. For example, we want to change the titles of all items in the Actors list by making them uppercase. With LiquidSilver, you can code like this:

// Prepare a list of HgBatchItemDictionary objects.
var batchItems = new List();
 
var items = list.Items;
foreach (SPListItem item in items)
{
  // The HgBatchItemDictionary constructor takes the item's ID as the
  // parameter.
  var batchItem = new HgBatchItemDictionary(item.ID);
 
  // HgBatchItemDictionary uses key-value pairs to specify the field and
  // the field's value of the item.
  batchItem["Title"] = item.Title.ToUpper();
 
  batchItems.Add(batchItem);
}
 
// Continue the batch process even though there is an error.
bool continueOnError = true;
 
new HgList(web.Lists["list name"])
  .BatchUpdate(continueOnError, batchItems.ToArray());

As seen in the code, we need to represent the items we want to update as HgBatchItemDictionary objects. It is a dictionary that uses the key to represent the item’s field (by specifying the field’s internal name), and the value to represent the item’s field’s value. You need to specify only the fields you want to update. HgBatchItemDictionary requires the item’s ID that can be provided using the constructor or the ItemId property.

You may have noticed that HgList is an object that wrap an SPList object, like the HgListItem object to the SPListItem object, which is demonstrated in the previous article. Please check other related articles if you are interested. Thanks.