Reputation: 1
I have an Angular 2+ application that happily execute calls via REST API to a SharePoint 2013 hosted in a different server. It works quite good but unfortunately for a very specific need (discussion boards) it's not enough. Here what I am doing:
async addMessageREST(callback, siteUrl, discussionBoardName, parentItemId, newMessageBody) {
const requestOptions = {
withCredentials: true,
crossDomain: true
};
var messagePayload = {
// '__metadata': { "type": "SP.Data.DiscussionsListItem" },
'Body': newMessageBody,
'ParentItemID': parentItemId, //unfortunately will be ignored
'FileSystemObjectType': 0,
'ContentTypeId': '0x0107008822E9328717EB48B3B665EE2266388E'
};
// retrieve the contextinfo
let contextinfo = await this._http
.post(
siteUrl + '/_api/contextinfo',
null,
requestOptions
)
.toPromise();
// finally post the request
const requestOptionsAddMessage = {
withCredentials: true,
crossDomain: true,
headers: new HttpHeaders().set('X-RequestDigest', contextinfo["FormDigestValue"]).set("Accept", "application/json;odata=verbose")
};
let request = "/_api/web/Lists/GetByTitle('" + discussionBoardName + "')/items";
let discussionItem = await this._http
.post(
siteUrl + request,
messagePayload,
requestOptionsAllMessages
)
.toPromise();
callback(discussionItem);
}
Technically this works fine, but unfortunately it's not enough because as you may know REST API doesn't offer specific functionalities to manage discussions items. For this JSOM provide quite good methods, but unfortunately I am not able to establish a connection with it (I get a 401 error). Here what I am doing:
addMessageJSOM(callback, siteUrl, discussionBoardName, parentTopicId, newMessageBody) {
let clientContext = new SP.ClientContext(siteUrl);
let list = clientContext.get_web().get_lists().getByTitle(discussionBoardName);
let discussionItem = list.getItemById(parentTopicId);
let properties = {
'Body': newMessageBody
};
let messageItem = SP.Utilities.Utility.createNewDiscussionReply(clientContext, discussionItem);
for (var propName in properties) {
messageItem.set_item(propName, properties[propName])
}
messageItem.update();
clientContext.executeQueryAsync(() => {
callback(messageItem);
}, (error: any) => {
console.log('Request failed', error);
});
}
All works good, until it comes to the executeQueryAsync, and I get the said 401 error. I suppose it's because somehow I am not passing the digest/the options that I am passing via HTTP in the REST Call. Any idea how I could pass these options via JSOM? Alternatively, there is a way to call the JSOM endpoint via HTTP without relying on the SP libraries?
Thanks in advance for your reading until here!
Upvotes: 0
Views: 138
Reputation: 1889
JSOM must rely on SP libraries. If you want to create discussion item via Rest API, you may take a reference of below demo:
function executeJson(options) {
var headers = options.headers || {};
var method = options.method || "GET";
headers["Accept"] = "application/json;odata=verbose";
if (options.method == "POST") {
headers["X-RequestDigest"] = $("#__REQUESTDIGEST").val();
}
var ajaxOptions =
{
url: options.url,
type: method,
contentType: "application/json;odata=verbose",
headers: headers
};
if ("data" in options) {
ajaxOptions.data = JSON.stringify(options.data);
}
return $.ajax(ajaxOptions);
}
function createListItem(webUrl, listTitle, payload) {
var url = webUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/items";
return executeJson({
"url": url,
"method": 'POST',
"data": payload
});
}
function moveListItem(webUrl, listTitle, itemId, folderUrl) {
var url = webUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/getItemById(" + itemId + ")?$select=FileDirRef,FileRef";
return executeJson({
"url": url
})
.then(function (result) {
var fileUrl = result.d.FileRef;
var fileDirRef = result.d.FileDirRef;
var moveFileUrl = fileUrl.replace(fileDirRef, folderUrl);
var url = webUrl + "/_api/web/getfilebyserverrelativeurl('" + fileUrl + "')/moveto(newurl='" + moveFileUrl + "',flags=1)";
return executeJson({
"url": url,
"method": 'POST'
});
});
}
function getParentTopic(webUrl, listTitle, itemId) {
var url = webUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/getItemById(" + itemId + ")/Folder";
return executeJson({
"url": url,
});
}
function createNewDiscussionReply(webUrl, listTitle, messagePayload) {
var topicUrl = null;
return getParentTopic(webUrl, listTitle, messagePayload.ParentItemID)
.then(function (result) {
topicUrl = result.d.ServerRelativeUrl;
return createListItem(webUrl, listTitle, messagePayload);
})
.then(function (result) {
var itemId = result.d.Id;
return moveListItem(webUrl, listTitle, itemId, topicUrl);
});
}
$(function () {
// Handler for .ready() called.
var listTitle = "discuss";
var webUrl = _spPageContextInfo.webAbsoluteUrl;
var messagePayload = {
'__metadata': { "type": "SP.Data.DiscussListItem" }, //set DiscussionBoard entity type name
'Body': "Thanks for the information", //message Body
'FileSystemObjectType': 0, //setto 0 to make sure Mesage Item
'ContentTypeId': '0x0107008822E9328717EB48B3B665EE2266388E', //set Message content type
'ParentItemID': 1 //set Discussion (topic) Id
};
createNewDiscussionReply(webUrl, listTitle, messagePayload)
.done(function (item) {
console.log('Message(reply) has been sent');
})
.fail(function (error) {
console.log(JSON.stringify(error));
});
});
More references:
BR
Upvotes: 0
Reputation: 43
can you change this below line so that parent item id wont be ignored
let request = "/_api/web/Lists/GetByTitle('" + discussionBoardName + "')/items(" + parentItemId + ")" ;
Upvotes: 0