I have read lots of articles on C# Corner, as well as on other online websites about CRUD operations on Sharepoint List. In most articles, I have found some redundant code which can be reused and utilized in such a way that any new developer or learner can learn from the code.
So, based on that, I have started working on creating SPRest Utility which will do lots of work internally to increase development speed with much less coding. As I am still working and it is not fully optimized, there is still redundant code and methods which I have to delete.
SPRest.js
- var SPRest = (function () {
- function SPRest(rootWeb) {
- var _this = this;
- this.Utils = (function () {
-
-
-
-
-
- var reqUrl = _this.rootUrl + "/_api/web/lists/getbytitle('AWSResponseList')/items";
-
-
-
- var spDefaultMeta = {
- List: {
- BaseTemplate: 100,
-
- __metadata: { type: "SP.List" }
- },
- Document: {
- __metadata: { type: "SP.List" },
- AllowContentTypes: true,
- BaseTemplate: 101,
- ContentTypesEnabled: true
-
-
- },
- ListItem: {
- __metadata: { type: "SP.Data.AWSResponseListListItem" }
-
- }
- };
- console.log(_this.rootUrl);
- var isOdataVerbose = true;
- var _rootUrl = _this.rootUrl;
-
- var _payloadOptions = {
- method: "GET",
- body: undefined,
- headers: {
- credentials: "include",
- Accept: "application/json; odata=verbose",
- "Content-Type": "application/json; odata=verbose"
- }
- };
-
-
-
-
-
-
-
- if (!isOdataVerbose) {
- _payloadOptions.headers.Accept = "application/json; odata=nometadata";
- }
-
-
-
- var getItemTypeForListName = function (name) {
- return ("SP.Data." +
- name.charAt(0).toUpperCase() +
- name
- .split(" ")
- .join("")
- .slice(1) +
- "ListItem");
- };
- var Get = function (url) {
- var _localPayload = _payloadOptions;
- _localPayload.method = "GET";
-
-
- _localPayload.body = undefined;
- delete _localPayload.headers["IF-MATCH"];
- delete _localPayload.headers["X-HTTP-Method"];
- console.log(_localPayload);
- return fetch(url, _localPayload).then(function (r) { return r.json(); });
- };
- var getRequestDigest = function (url) {
- if (url === void 0) { url = ""; }
- if (url) {
- url = _this.rootUrl;
- }
- url += "/_api/contextinfo";
- var _localPayload = _payloadOptions;
- _localPayload.method = "POST";
- return fetch(url, _payloadOptions).then(function (r) { return r.json(); });
- };
- var postWithRequestDigestExtension = function (url, _a) {
- var _b = _a.headers, headers = _b === void 0 ? {} : _b, payload = _a.payload;
- return getRequestDigest().then(function (token) {
-
- headers["X-RequestDigest"] =
- token.d.GetContextWebInformation.FormDigestValue;
- return PostExtension(url, { headers: headers, payload: payload });
- });
- };
- var postWithRequestDigest = function (url, payload) {
- return getRequestDigest().then(function (token) {
- payload.requestDigest =
- token.d.GetContextWebInformation.FormDigestValue;
- return Post(url, payload);
- });
- };
-
-
-
- var updateWithRequestDigest = function (url, payload) {
- return getRequestDigest(payload.rootUrl + "/_api/contextinfo").then(function (token) {
- payload.requestDigest =
- token.d.GetContextWebInformation.FormDigestValue;
- payload._extraHeaders = {
- "IF-MATCH": "*",
- "X-HTTP-Method": "MERGE"
- };
-
- payload.isNoJsonResponse = true;
- return Post(url, payload);
- });
- };
- var deleteWithRequestDigest = function (url, payload) {
- return getRequestDigest(payload.rootUrl + "/_api/contextinfo").then(function (token) {
- payload.requestDigest =
- token.d.GetContextWebInformation.FormDigestValue;
- payload._extraHeaders = {
- "IF-MATCH": "*",
- "X-HTTP-Method": "DELETE"
- };
-
- payload.isNoJsonResponse = true;
- return Post(url, payload);
- });
- };
- var Post = function (url, payload) {
- var _localPayload = _payloadOptions;
-
-
- _localPayload.method = "POST";
- _localPayload.body = payload.data;
- var _metaInfo = payload.metaInfo;
-
- if (_metaInfo && spDefaultMeta[_metaInfo.type]) {
-
- var type = _metaInfo.type, title = _metaInfo.title, listName = _metaInfo.listName;
- var _body = spDefaultMeta[type];
- if (title) {
-
- _body.Title = title;
- }
- if (type === "ListItem") {
-
- _body.__metadata.type = getItemTypeForListName(listName);
- }
-
-
- if (payload.extraFields) {
- for (var field in payload.extraFields) {
-
-
- _body[field] = payload.extraFields[field];
- }
-
-
- }
-
- _localPayload.body = JSON.stringify(_body);
- _localPayload.body.Title = title;
- }
-
- if (payload._extraHeaders) {
- for (var _header in payload._extraHeaders) {
- _localPayload.headers[_header] = payload._extraHeaders[_header];
- }
- }
- else {
-
- _localPayload.headers["IF-MATCH"] = undefined;
- _localPayload.headers["X-HTTP-Method"] = undefined;
- }
- _localPayload.headers["X-RequestDigest"] = payload.requestDigest;
- console.log(_localPayload);
-
- if (payload.isNoJsonResponse) {
- return fetch(url, _localPayload).then(function (r) { return r; });
- }
- else {
- return fetch(url, _localPayload).then(function (r) { return r.json(); });
- }
- };
- var PostExtension = function (url, _a) {
- var headers = _a.headers, payload = _a.payload;
- var _localPayload = {};
- _localPayload = _payloadOptions;
-
-
- _localPayload.method = "POST";
-
- if (headers) {
- for (var _header in headers) {
- _localPayload.headers[_header] = headers[_header];
- }
- }
-
-
-
-
-
-
-
- _localPayload.body = JSON.stringify(payload.data);
-
-
-
-
- if (payload.isNoJsonResponse) {
- return fetch(url, _localPayload).then(function (r) { return r; });
- }
- else {
- return fetch(url, _localPayload).then(function (r) { return r.json(); });
- }
- };
-
-
-
-
- function generateUUID() {
- var d = new Date().getTime();
- var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
- var r = (d + Math.random() * 16) % 16 | 0;
- d = Math.floor(d / 16);
- return (c == "x" ? r : (r & 0x7) | 0x8).toString(16);
- });
- return uuid;
- }
-
-
-
-
- var GenerateBatchRequest = function (_a) {
- var _b = _a.listName, listName = _b === void 0 ? "" : _b, data = _a.data, _c = _a.DigestValue, DigestValue = _c === void 0 ? "" : _c, _d = _a.action, action = _d === void 0 ? "ADD" : _d, _e = _a.itemIds, itemIds = _e === void 0 ? [] : _e;
-
- var batchGuid = generateUUID();
-
- var batchContents = new Array();
- var changeSetId = generateUUID();
-
-
-
-
-
-
-
-
- for (var _index = 0; _index < data.length; _index++) {
-
- var _item = data[_index];
- if (action === "UPDATE") {
- _item.Title = "##Updated_" + _item.Title;
- }
-
- switch (action) {
- case "ADD":
- var endpoint = generateRestRequest({ listName: listName, type: "ListItem" });
- break;
- case "UPDATE":
- var endpoint = generateRestRequest({
- listName: listName,
- type: "ListItem",
- Id: itemIds[_index]
- });
- _item.Title += _index;
- break;
- case "DELETE":
- var endpoint = generateRestRequest({
- listName: listName,
- type: "ListItem",
- Id: itemIds[_index]
- });
- break;
- }
-
-
- batchContents.push("--changeset_" + changeSetId);
- batchContents.push("Content-Type: application/http");
- batchContents.push("Content-Transfer-Encoding: binary");
- batchContents.push("");
- if (action === "UPDATE") {
- batchContents.push("PATCH " + endpoint + " HTTP/1.1");
- batchContents.push("If-Match: *");
- batchContents.push("Content-Type: application/json;odata=verbose");
- batchContents.push("");
- batchContents.push(JSON.stringify(_item));
- }
- else if (action === "ADD") {
- batchContents.push("POST " + endpoint + " HTTP/1.1");
- batchContents.push("Content-Type: application/json;odata=verbose");
- batchContents.push("");
- batchContents.push(JSON.stringify(_item));
- }
- else if (action === "DELETE") {
- batchContents.push("DELETE " + endpoint + " HTTP/1.1");
- batchContents.push("If-Match: *");
- }
-
-
-
-
-
- batchContents.push("");
- }
-
- batchContents.push("--changeset_" + changeSetId + "--");
-
- var batchBody = batchContents.join("\r\n");
- batchContents = [];
-
- batchContents.push("--batch_" + batchGuid);
- batchContents.push('Content-Type: multipart/mixed; boundary="changeset_' +
- changeSetId +
- '"');
- batchContents.push("Content-Length: " + batchBody.length);
- batchContents.push("Content-Transfer-Encoding: binary");
- batchContents.push("");
- batchContents.push(batchBody);
- batchContents.push("");
-
-
-
-
-
-
-
-
-
-
-
-
-
- batchContents.push("--batch_" + batchGuid + "--");
- batchBody = batchContents.join("\r\n");
-
- var batchEndpoint = _this.rootUrl + "/_api/$batch";
-
-
-
-
- return getRequestDigest().then(function (r) {
-
- var batchRequestHeader = {
- "X-RequestDigest": r.d.GetContextWebInformation.FormDigestValue,
- "Content-Type": 'multipart/mixed; boundary="batch_' + batchGuid + '"'
- };
- return fetch(batchEndpoint, {
- method: "POST",
- headers: batchRequestHeader,
- body: batchBody
- }).then(function (r) { return r.text(); });
- });
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- };
- var generateRestRequest = function (_a) {
- var _b = _a.listName, listName = _b === void 0 ? "" : _b, _c = _a.Id, Id = _c === void 0 ? "" : _c, type = _a.type, _d = _a.oDataOption, oDataOption = _d === void 0 ? "" : _d, _e = _a.url, url = _e === void 0 ? "" : _e;
- if (url) {
- return url;
- }
- var prepareRequest = _this.rootUrl + "/_api/web/lists";
- switch (type) {
- case "ListItem":
- prepareRequest += "/getbytitle('" + listName + "')/items";
- if (Id) {
- prepareRequest += "(" + Id + ")";
- }
- if (oDataOption) {
- prepareRequest += "?" + oDataOption;
- }
- break;
- case "List":
- if (listName) {
- prepareRequest += "/getbytitle('" + listName + "')";
- }
- if (oDataOption) {
- prepareRequest += "?" + oDataOption;
- }
-
- break;
- case "MSGraph":
-
-
- break;
- }
-
-
-
-
-
- return prepareRequest;
- };
-
- var ListItem = {
- Add: function (_a) { },
- Update: function (_a) { },
- Delete: function (_a) { },
- GetItemById: function (_a) { },
- GetAllItem: function (_a) { }
- };
- var List = {
- Add: function (_a) { },
- Update: function (_a) {
- console.log("Implementation is pending");
- },
- Delete: function (_a) {
- console.log("Implementation is pending");
- },
- GetByTitle: function (_a) {
- console.log("Implementation is pending");
- },
- GetAll: function (_a) { }
- };
- List.GetAll = function (_a) {
- var _b = _a.oDataOption, oDataOption = _b === void 0 ? "" : _b, _c = _a.url, url = _c === void 0 ? "" : _c;
- return Get(generateRestRequest({ listName: "", type: "List", oDataOption: oDataOption, url: url }));
- };
- List.GetByTitle = function (_a) {
- var listName = _a.listName, oDataOption = _a.oDataOption, url = _a.url;
- return Get(generateRestRequest({ listName: listName, type: "List", oDataOption: oDataOption, url: url }));
- };
- List.Add = function (_a) {
- var listName = _a.listName, data = _a.data;
- var _reqUrl = generateRestRequest({ listName: listName, type: "List" });
- var _prePayload = preparePayloadData({
- action: "ADD",
- type: "List",
- listName: listName,
- data: data
- });
- return postWithRequestDigestExtension(_reqUrl, _prePayload);
- };
- ListItem.GetAllItem = function (_a) {
- var listName = _a.listName, _b = _a.oDataOption, oDataOption = _b === void 0 ? "" : _b, _c = _a.url, url = _c === void 0 ? "" : _c;
- return Get(generateRestRequest({ listName: listName, type: "ListItem", oDataOption: oDataOption, url: url }));
- };
- ListItem.GetItemById = function (_a) {
- var listName = _a.listName, Id = _a.Id, _b = _a.oDataOption, oDataOption = _b === void 0 ? "" : _b, _c = _a.url, url = _c === void 0 ? "" : _c;
- return Get(generateRestRequest({ listName: listName, Id: Id, type: "ListItem", oDataOption: oDataOption, url: url }));
- };
-
- ListItem.Add = function (_a) {
- var listName = _a.listName, data = _a.data;
- var _reqUrl = generateRestRequest({ listName: listName, type: "ListItem" });
- var _prePayload = preparePayloadData({
- action: "ADD",
- type: "ListItem",
- listName: listName,
- data: data
- });
- return postWithRequestDigestExtension(_reqUrl, _prePayload);
- };
- ListItem.Update = function (_a) {
- var listName = _a.listName, Id = _a.Id, data = _a.data;
- var _reqUrl = generateRestRequest({ listName: listName, Id: Id, type: "ListItem" });
- var _prePayload = preparePayloadData({
- action: "UPDATE",
- type: "ListItem",
- listName: listName,
- data: data
- });
- return postWithRequestDigestExtension(_reqUrl, _prePayload);
- };
- ListItem.Delete = function (_a) {
- var listName = _a.listName, Id = _a.Id, data = _a.data;
- var _reqUrl = generateRestRequest({ listName: listName, Id: Id, type: "ListItem" });
- var _prePayload = preparePayloadData({
- action: "DELETE",
- type: "ListItem",
- listName: listName,
- data: data
- });
- return postWithRequestDigestExtension(_reqUrl, _prePayload);
- };
- var preparePayloadData = function (_a) {
- var listName = _a.listName, data = _a.data, action = _a.action, type = _a.type;
- var payload = {
- data: { __metadata: spDefaultMeta[type] }
- };
-
-
-
-
- switch (type) {
- case "ListItem":
-
- payload.data.__metadata.type = getItemTypeForListName(listName);
- break;
- }
-
- if (data) {
- for (var _key in data) {
- payload.data[_key] = data[_key];
- }
- }
-
-
-
-
-
- var _headers = {};
- switch (action) {
- case "ADD":
- _headers = {
- "IF-MATCH": undefined,
- "X-HTTP-Method": undefined
- };
- break;
- case "UPDATE":
- _headers = {
- "IF-MATCH": "*",
- "X-HTTP-Method": "MERGE"
- };
-
- payload.isNoJsonResponse = true;
- break;
- case "DELETE":
- _headers = {
- "IF-MATCH": "*",
- "X-HTTP-Method": "DELETE"
- };
-
- payload.isNoJsonResponse = true;
- break;
- }
- return { headers: _headers, payload: payload };
- };
- return {
- ListItem: ListItem,
- Get: Get,
- getRequestDigest: getRequestDigest,
- Post: postWithRequestDigest,
- Update: updateWithRequestDigest,
- Delete: deleteWithRequestDigest,
- BatchInsert: GenerateBatchRequest
- };
- })();
- this.rootUrl = rootWeb;
- }
- return SPRest;
- }());
You might be wondering how to use SPRest for CRUD Operation in SharePoint.
First of all, save the above code in a file and then, add the reference to it on the page wherever you want to use it.
If you want to use this SPRest utility in your SPFx web part or add it using TypeScript, then you can find compatible SpRest.ts at
my repo.
Once you have added references, then create the instance of SPRest with one parameter which accepts Sharepoint rootUrl used internally or generating request URL for REST API.
- var spRest=new SPRest("https://brgrp.sharepoint.com")
For demonstration purposes, I am using "PlaceHolderList" that is having the following columns.
- Title -Single line of Text
- UserId - Number
- Completed -Single line of Text
Get All List Items from Sharepoint List
By default, SharePoint List returns the top 100 records if you have more than 100 records in the list.
-
- spRest.Utils.ListItem.GetAllItem({listName:"PlaceHolderList"}).then(function(r){
- console.log(r);
-
- });
Get All List Items from Sharepoint List using URL or with oDataOption
Get Selected columns using $select and use $top in oDataOptions from the list or you can use full URL which will directly pass to get data based on the option in URL.
Here you can request list item with your selected column and filter in URL, you can use all supported odata option in URL to get full
response,
Or
you can just pass list name other oDataOption as shown below without adding a question mark at starting to get same data and if you required next paginated response you can just pass "__next" in url.
-
- util.Utils.ListItem
- .GetAllItem({
- url:"https://brgrp.sharepoint.com/_api/web/lists/getbytitle('PlaceHolderList')/items?$select=Id,Title&$top=200"
- }).then(function(r){console.log(r);
-
- });
-
-
-
- util.Utils.ListItem.GetAllItem(
- {"listName":"PlaceHolderList"
- ,oDataOption:"$select=Id,Title&$top=200"
- }).then(function(r){console.log(r);
-
- });
Note
Here if you have passed both listname and url then query will be executed based on only url, listName and oDataOption value not considered.
Get List Item from SharePoint List by Id
-
- spRest.Utils.ListItem.GetItemById({listName:"PlaceHolderList",Id:201}).then(function(r){
- console.log(r);
-
- });
Add New List Item to SharePoint List
-
- spRest.Utils.ListItem.Add({listName:"PlaceHolderList",data:{Title:"New Item Created For Demo",UserId:1,Completed:"true"}}).then(function(r){
- console.log(r);
-
- });
Update New List Item By Id in SharePoint List
-
- spRest.Utils.ListItem.Update({listName:"PlaceHolderList",Id:201,data:{Title:"Updated List Item",UserId:1,Completed:"true"}}).then(function(r){
-
- console.log(r);
- });
Delete New List Item By Id in SharePoint List
-
- spRest.Utils.ListItem.Delete({listName:"PlaceHolderList",Id:201}).then(function(r){
-
- console.log(r);
- });
As per the above code example for CRUD functionality, it looks like a cleaner and easier way to perform the CRUD opeation on SharePoint List. It has a lot of redundant code.
- Generate Request Url Based on Root Site and List Name and Id
- Header accept and Content type
- RequestDigest Headers
- Combined Delete/Update/Add Code with reusable functions to prepare payload data for the request
- Adding and applying metadata for ListItem based on ListName
I removed and combined with reusable functions so it can be used for extending List and Document Library in the future.
I hope you find this article and utilities helpful. Let me know your comments and any suggestion to extend SPRest util.
All implementation and source code for SPRest can be found on
GitHub.
Change History:
18-Apr-2018: Updated SPRest.js to support oDataOption and direct URL as a parameter in util function to get the paginated item.
Conclusion
In this article, we have learned about an easy and cleaner way to do CRUD Operations with SharePoint List Items using SPRest.