SPServices is a great tool, really nice work, Marc Anderson (@sympmarc). It has been there all the time I have developed for SharePoint. But the fact that you work with XML and you must parse the attributes (!) was the reason why I prefered listdata.svc and Client Object Model, where you get objects in JSON or you have a nice API to get objects and their properties. But there is an area where SPServices are really the best tool: SharePoint Web Services which only understand SOAP like SocialDataService.asmx.
Three ways to get list items
Just a little comparison. We’ll retrieve Titles from Tasks list (Oppgaver in nb-no).
listdata.svc
$.getJSON("/_vti_bin/ListData.svc/Oppgaver()?$select=Tittel")
.done(function(data){
var tasks = data.d.results;
for(var t in tasks) {
var title = tasks[t].Tittel;
console.log(title);
}
})
.fail(function() {
console.log("error");
});
Pay attention to the field name: Tittel. I think it is the biggest shortcoming of listdata.svc: the fact that we can’t use the internal (static) field names.
Client Object Model
var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
var taskList = web.get_lists().getByTitle("Oppgaver");
var query = new SP.CamlQuery("<ViewFields><FieldRef Name='Title' /></ViewFields>");
var tasks = taskList.getItems(query);
ctx.load(tasks);
ctx.executeQueryAsync(function() {
var listEnumerator = tasks.getEnumerator();
while(listEnumerator.moveNext()) {
var task = listEnumerator.get_current();
var title = task.get_item("Title");
console.log(title);
}
}, function() {
console.log("error");
});
SPServices
$().SPServices({
operation: "GetListItems",
async: true,
listName: "Oppgaver",
CAMLViewFields: "<ViewFields><FieldRef Name='Title' /></ViewFields>",
completefunc: function (xData, Status) {
$(xData.responseXML).SPFilterNode("z:row").each(function() {
console.log( $(this).attr("ows_Title") );
});
}
});
SPServices and SocialDataService
Let’s try to find the count of comments for an url. To do so we must create a SOAP envelope in javascript, send it and handle the response result:
var strUrl = "http://dev/Sider/Help.aspx";
var request = "<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> \
<CountCommentsOnUrl \
xmlns='http://microsoft.com/webservices/SharePointPortalServer/SocialDataService'> \
<url>" + strUrl + "</url> \
</CountCommentsOnUrl> \
</soap:Body> \
</soap:Envelope>";
jQuery.ajax({
type: "POST",
async: true,
url: '/_vti_bin/SocialDataService.asmx?op=CountCommentsOnUrl',
data: request,
contentType: "text/xml; charset=utf-8",
dataType: "xml",
success: function (content, txtFunc, xhr) {
var count = jQuery(content).find('CountCommentsOnUrlResult').text();
console.log(count);
}
});
It works but, we have to handle the creating of SOAP envelope in our javascript code which can be error prone. SPServices provides a nice abstraction layer and handles many scenarios. The same operation in SPServices:
$().SPServices({
operation: "CountCommentsOnUrl",
async: true,
url:"http://dev/Sider/Help.aspx",
completefunc: function (xData, Status) {
var result = $(xData.responseXML).find("CountCommentsOnUrlResult")[0];
console.log($(result).text());
}
});
In both cases we have to iterate through responseXML. This is a sample responseXML for CountCommentsOnUrl from SocialDataService.asmx:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<CountCommentsOnUrlResponse
xmlns="http://microsoft.com/webservices/SharePointPortalServer/SocialDataService">
<CountCommentsOnUrlResult>1</CountCommentsOnUrlResult>
</CountCommentsOnUrlResponse>
</soap:Body>
</soap:Envelope>
Recent Comments