SharePoint Hosted Apps: Working with version history of Multiple Lines of Text column

Recently while extending one of my SharePoint Hosted Apps, I stumbled upon a road block using REST API and JavaScript Object Model (JSOM).  To explain context,  here is the scenario:

 

A list contains a "Multiple lines of Text" column with "Append Changes to Existing Text" set to "Yes".  We need to fetch the text, current and previously entered, the name of person who entered the text, and the time it was entered.  We need to sort the information from newest to oldest.

At first, I thought it would be piece of cake.  Maybe expand would work with REST API and return all related content.  Nope.  Okay, maybe load the column value using JSOM.  Nope.  Hmm.  Time for Bing search.  Going through the results, I came across an article on the second page.  The title, "How to get Versioned Multi Line Text." 

 

Light bulb!  When saving the "Multiple lines of Text" column with "Append Changes to Existing Text" set to "Yes", a message box politely reminds you that "You must first turn on versioning in this list before adding or creating columns which append changes to existing text". 

Does that mean that I need to get all the versions for the item, and check all to make sure it includes the column I am looking for?  Another article on MSDN added further disappointment.  I can use "GetFileByServerRelativeUrl" to get the version information using REST API and JSOM but it does not give any details on what exactly changed.  Ouch.  This is certainly possible using Server Side Object Model (SSOM) but it seems that REST API and JSOM team forgot to add this to client side.

 

Let's cut the chase.  After going through several articles for a couple of days, it was time for redemption.

 

On codeplex, there is a jQuery library named SPServices which abstracts SharePoint Web Services and it works entirely client side.  Question:  how?  Another search on using SPServices with SharePoint apps did not give any comforting response as some users had problems with making it work with SharePoint apps.  Time to dig in.

 

It was time to go over SharePoint Web Services.  In the list, I found the "Lists Web Service".  The lists class has a method "GetVersionCollection" which takes a list ID (GUID), item ID, and internal field name.  **Bingo. **

First test, append "/_vti_bin/lists.asmx" to the end of the appweburl and voila, it gives me a list of available methods.  Clicking on the "GetVersionCollection" method link brings up the details.  Now all I need to do is build a soap request, call the service, and parse the soap response.  Here is what I ended up with:

var soapPack = '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' +
                                    '<soap:Body>' +
                                    '<GetVersionCollection xmlns="http://schemas.microsoft.com/sharepoint/soap/">' +
                                    '<strlistID>2392332-909080-909090-0990803</strlistID>' +
                                    '<strlistItemID>50</strlistItemID>' +
                                    '<strFieldName>InternalFieldName</strFieldName>' +
                                    '</GetVersionCollection>' +
                                    '</soap:Body>' +
                                    '</soap:Envelope>';
 
    $.ajax({
        type: "POST",
        url: appweburl + '/_vti_bin/lists.asmx',
        data: soapPack,
        dataType: "xml",
        contentType: "text/xml; charset=\"utf-8\"",
        success: function  (xData, status) {
            $(xData).find("Versions").find("Version").each(function () {
                alert($(this).attr("Editor"));
                alert($(this).attr("Modified"));
                alert($(this).attr("InternalFieldName"));
            });
        },
        error: function  (e) {
            alert("Unable to fetch comment history");
        }
    });

Needless to say that you would need a jQuery library.  We can put each item in an array and sort it by "Modified" in descending order.

Conclusion

I have come to the same conclusion one too many times.  No one API can fulfill all of our requirements and there would always remain a need to mix and match the APIs available.

References

Windows SharePoint Services 3.0

Choose the right API set in SharePoint 2013