SharePoint with Angular
I have been working on a SharePoint Intranet project that uses AngularJS. Here is some code sample for using Angular with SharePoint. The sample code below basically is:
I have the following files
The files contain are pasted below.
***appFactory.js*********************************
var spServices = angular.module('spServices', []);
//Factory with SharePoint call using JSOM
spServices.factory('SPRestSearchFactory', ['$resource',
function ($resource) {
return $resource(_spPageContextInfo.siteAbsoluteUrl + "/_api/search/query/:searchtext", { searchtext: '@querytext' }, {
query: {
method: 'GET', isArray: false,
headers: { "Accept": "application/json; odata=verbose", 'Content-Type': 'application/json;odata=verbose;' }
}
});
}]);
spServices.factory('SPRestServicesFactory', function ($q) {
var getListItems = function (url, listName, params) {
var deferred = $q.defer();
$.ajax({
url: url + "/_api/web/lists/getbytitle('" + listName + "')/items" + params,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
// Returning the results
deferred.resolve(data);
},
error: function (data) {
//deferred.reject(sender, args);
}
});
return deferred.promise
};
return {
GetListItems: getListItems
};
});
spServices.factory('SPServicesFactory', function ($q) {
var getSearchResults = function (searchQuery, props, rowLimit) {
var deferred = $q.defer();
var clientContext = SP.ClientContext.get_current();
var keywordQuery = new Microsoft.SharePoint.Client.Search.Query.KeywordQuery(clientContext);
var queryText = searchQuery;
keywordQuery.set_queryText(queryText);
var properties = keywordQuery.get_selectProperties();
for (i = 0; i < props.length; i++) {
properties.add(props[i]);
}
keywordQuery.set_rowLimit(rowLimit);
var searchExecutor = new Microsoft.SharePoint.Client.Search.Query.SearchExecutor(clientContext);
searchResults = searchExecutor.executeQuery(keywordQuery);
clientContext.executeQueryAsync(
Function.createDelegate(this,
function () { deferred.resolve(searchResults); }),
Function.createDelegate(this,
function (sender, args) { deferred.reject(sender, args); }));
return deferred.promise;
};
//Since client object model doesn't support update to user profile properties, we'll need to use the old //web services to get that done.
var setUserProfile = function (accountName, propertyName, propertyValue) {
var newData = '<?xml version="1.0" encoding="utf-8"?>'
+ '<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>' + ' <ModifyUserPropertyByAccountName xmlns="http://microsoft.com/webservices/SharePointPortalServer/UserProfileService">'
+ ' <accountName>' + accountName + '</accountName>'
+ ' <newData>'
+ ' <PropertyData>'
+ ' <IsPrivacyChanged>false</IsPrivacyChanged>'
+ ' <IsValueChanged>true</IsValueChanged>'
+ ' <Name>' + propertyName + '</Name>'
+ ' <Privacy>Public</Privacy>'
+ ' <Values><ValueData><Value xsi:type="xsd:string">'
+ propertyValue + '</Value></ValueData></Values>'
+ ' </PropertyData>'
+ ' </newData>'
+ ' </ModifyUserPropertyByAccountName>'
+ ' </soap:Body>'
+ '</soap:Envelope>'
var deferred = $q.defer();
$.ajax({
url: '/_vti_bin/UserProfileService.asmx',
beforeSend: function (xhr) {
xhr.setRequestHeader("SOAPAction", "http://microsoft.com/webservices/SharePointPortalServer/UserProfileService/ModifyUserPropertyByAccountName")
},
type: "POST",
async: false,
dataType: "xml",
data: newData,
contentType: "text/xml; charset=\"utf-8\"",
complete: function (xmlHttpRequest, status) {
//do nothing
deferred.resolve();
},
error: function (jqXHR, textStatus, errorThrown) {
//deferred.reject(sender, args);
}
});
return deferred.promise;
};
//Get current user login name
var getCurrentUser = function () {
var deferred = $q.defer();
var requestUri = _spPageContextInfo.webAbsoluteUrl + "/_api/web/getuserbyid(" + _spPageContextInfo.userId + ")";
var requestHeaders = { "accept": "application/json;odata=verbose" };
var loginName = "";
$.ajax({
url: requestUri,
async: false,
contentType: "application/json;odata=verbose",
headers: requestHeaders,
success: function (data, request) {
try {
loginName = data.d.LoginName.split('|')[1].toString();
deferred.resolve(loginName);
}
catch (err) {
deferred.reject(sender, args);
}
},
error: function (jqXHR, textStatus, errorThrown) { deferred.reject(sender, args); }
});
return deferred.promise;
};
return {
getSearchResults: getSearchResults,
GetCurrentUser: getCurrentUser,
SetUserProfile: setUserProfile
};
});
//Getting list items using REST
spServices.factory('SPRestServicesFactory', function ($q) {
var getListItems = function (url, listName, params) {
var deferred = $q.defer();
$.ajax({
url: url + "/_api/web/lists/getbytitle('" + listName + "')/items" + params,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
// Returning the results
deferred.resolve(data);
},
error: function (data) {
//deferred.reject(sender, args);
}
});
return deferred.promise
};
return {
GetListItems: getListItems
};
});
****** app.js ********************************
var spApp = angular.module('spApp', ['spServices']);
spApp.directive('aymhiList', ['SPRestServicesFactory', function ($spRestServices) {
return {
restrict: 'E',
transclude: true, // make parent scope available
templateUrl: 'list.html',
replace: true,
link: function (scope, element, attributes) {
scope.getList = function () {
$spRestServices.GetListItems(_spPageContextInfo.siteAbsoluteUrl, "Custom List", "?$orderby=Order").then(function (data) {
scope.items = data.d.results;
});
var props = ["Title", "Path"];
$spSearch.getSearchResults("Title:Test", props, 30).then(function (data) {
scope.results = data.m_value.ResultTables[0].ResultRows;
});
};
scope.getList();
}
};
}]);
***list.html***********************************************************
<div>
<ul>
<li ng-repeat="item in items" id="{{item.Id}}">{{item.Title}}</li>
</ul>
<div id="searchResultDiv">
<ul>
<li ng-repeat="result in results"><a href="{{result.Path}}">{{result.Title}}</a></li>
</ul>
</div>
</div>
- Getting a items from a list
- Searching for items with Title containing "Test"
- Display the results from the list and search onto the page
I have the following files
- appFactory.js - for handling the services call to SharePoint using both JSOM and REST
- app.js - the main application logic (including a custom directive)
- list.html - the html template for my directive
The files contain are pasted below.
***appFactory.js*********************************
var spServices = angular.module('spServices', []);
//Factory with SharePoint call using JSOM
spServices.factory('SPRestSearchFactory', ['$resource',
function ($resource) {
return $resource(_spPageContextInfo.siteAbsoluteUrl + "/_api/search/query/:searchtext", { searchtext: '@querytext' }, {
query: {
method: 'GET', isArray: false,
headers: { "Accept": "application/json; odata=verbose", 'Content-Type': 'application/json;odata=verbose;' }
}
});
}]);
spServices.factory('SPRestServicesFactory', function ($q) {
var getListItems = function (url, listName, params) {
var deferred = $q.defer();
$.ajax({
url: url + "/_api/web/lists/getbytitle('" + listName + "')/items" + params,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
// Returning the results
deferred.resolve(data);
},
error: function (data) {
//deferred.reject(sender, args);
}
});
return deferred.promise
};
return {
GetListItems: getListItems
};
});
spServices.factory('SPServicesFactory', function ($q) {
var getSearchResults = function (searchQuery, props, rowLimit) {
var deferred = $q.defer();
var clientContext = SP.ClientContext.get_current();
var keywordQuery = new Microsoft.SharePoint.Client.Search.Query.KeywordQuery(clientContext);
var queryText = searchQuery;
keywordQuery.set_queryText(queryText);
var properties = keywordQuery.get_selectProperties();
for (i = 0; i < props.length; i++) {
properties.add(props[i]);
}
keywordQuery.set_rowLimit(rowLimit);
var searchExecutor = new Microsoft.SharePoint.Client.Search.Query.SearchExecutor(clientContext);
searchResults = searchExecutor.executeQuery(keywordQuery);
clientContext.executeQueryAsync(
Function.createDelegate(this,
function () { deferred.resolve(searchResults); }),
Function.createDelegate(this,
function (sender, args) { deferred.reject(sender, args); }));
return deferred.promise;
};
//Since client object model doesn't support update to user profile properties, we'll need to use the old //web services to get that done.
var setUserProfile = function (accountName, propertyName, propertyValue) {
var newData = '<?xml version="1.0" encoding="utf-8"?>'
+ '<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>' + ' <ModifyUserPropertyByAccountName xmlns="http://microsoft.com/webservices/SharePointPortalServer/UserProfileService">'
+ ' <accountName>' + accountName + '</accountName>'
+ ' <newData>'
+ ' <PropertyData>'
+ ' <IsPrivacyChanged>false</IsPrivacyChanged>'
+ ' <IsValueChanged>true</IsValueChanged>'
+ ' <Name>' + propertyName + '</Name>'
+ ' <Privacy>Public</Privacy>'
+ ' <Values><ValueData><Value xsi:type="xsd:string">'
+ propertyValue + '</Value></ValueData></Values>'
+ ' </PropertyData>'
+ ' </newData>'
+ ' </ModifyUserPropertyByAccountName>'
+ ' </soap:Body>'
+ '</soap:Envelope>'
var deferred = $q.defer();
$.ajax({
url: '/_vti_bin/UserProfileService.asmx',
beforeSend: function (xhr) {
xhr.setRequestHeader("SOAPAction", "http://microsoft.com/webservices/SharePointPortalServer/UserProfileService/ModifyUserPropertyByAccountName")
},
type: "POST",
async: false,
dataType: "xml",
data: newData,
contentType: "text/xml; charset=\"utf-8\"",
complete: function (xmlHttpRequest, status) {
//do nothing
deferred.resolve();
},
error: function (jqXHR, textStatus, errorThrown) {
//deferred.reject(sender, args);
}
});
return deferred.promise;
};
//Get current user login name
var getCurrentUser = function () {
var deferred = $q.defer();
var requestUri = _spPageContextInfo.webAbsoluteUrl + "/_api/web/getuserbyid(" + _spPageContextInfo.userId + ")";
var requestHeaders = { "accept": "application/json;odata=verbose" };
var loginName = "";
$.ajax({
url: requestUri,
async: false,
contentType: "application/json;odata=verbose",
headers: requestHeaders,
success: function (data, request) {
try {
loginName = data.d.LoginName.split('|')[1].toString();
deferred.resolve(loginName);
}
catch (err) {
deferred.reject(sender, args);
}
},
error: function (jqXHR, textStatus, errorThrown) { deferred.reject(sender, args); }
});
return deferred.promise;
};
return {
getSearchResults: getSearchResults,
GetCurrentUser: getCurrentUser,
SetUserProfile: setUserProfile
};
});
//Getting list items using REST
spServices.factory('SPRestServicesFactory', function ($q) {
var getListItems = function (url, listName, params) {
var deferred = $q.defer();
$.ajax({
url: url + "/_api/web/lists/getbytitle('" + listName + "')/items" + params,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
// Returning the results
deferred.resolve(data);
},
error: function (data) {
//deferred.reject(sender, args);
}
});
return deferred.promise
};
return {
GetListItems: getListItems
};
});
****** app.js ********************************
var spApp = angular.module('spApp', ['spServices']);
spApp.directive('aymhiList', ['SPRestServicesFactory', function ($spRestServices) {
return {
restrict: 'E',
transclude: true, // make parent scope available
templateUrl: 'list.html',
replace: true,
link: function (scope, element, attributes) {
scope.getList = function () {
$spRestServices.GetListItems(_spPageContextInfo.siteAbsoluteUrl, "Custom List", "?$orderby=Order").then(function (data) {
scope.items = data.d.results;
});
var props = ["Title", "Path"];
$spSearch.getSearchResults("Title:Test", props, 30).then(function (data) {
scope.results = data.m_value.ResultTables[0].ResultRows;
});
};
scope.getList();
}
};
}]);
***list.html***********************************************************
<div>
<ul>
<li ng-repeat="item in items" id="{{item.Id}}">{{item.Title}}</li>
</ul>
<div id="searchResultDiv">
<ul>
<li ng-repeat="result in results"><a href="{{result.Path}}">{{result.Title}}</a></li>
</ul>
</div>
</div>
Comments