Updating metadata file in sharepoint online via REST API - node.js

I upload a file to sharepoint and trying to update its metadata, but I always get error 400 in last step.
As far as I understand, sharepoint only handles lists and items. A "folder" is a list and both metadata and files inside are items. And a "file" is a list and its metadata are items.
Documentation about updating metadata say about to make a POST request to:
https: // {site_url} / _api / web / lists / GetByTitle ('{list_title}') / items ({item_id})
Updating files must be done by PUT method (not MERGE allowed), but updating metadata must be done specifically by MERGE method. I have tried both, and both failed.
This is my current updating metadata request, but I'm continuing getting an error 400.
var data = {
"__metadata": {
"type":type
},
"Description":"lorem ipsum"
};
var headerToken = {
headers: {
'Authorization':'Bearer ' + token
, 'X-HTTP-Method':'MERGE'
, 'Accept':'application/json;odata=verbose'
, 'Content-Type':'application/json;odata=verbose'
, 'Content-Length':JSON.stringify(data).length
, 'If-Match': etag
, 'X-RequestDigest': digest
}
};
try {
var response = await axios.post(
'https://{site_url}/_api/web/lists/GetByTitle("'+MY_FOLDER+'")/items('+id+')'
, JSON.stringify(data)
, headerToken
);
return response;
}
type, etag and id are get from uploading file response and digest is get from a request to contextinfo endpoint. MY_FOLDER is a test library and at this moment is a constant.

You need to use single quotes in getbytitle.
"https://{site_url}/_api/web/lists/GetByTitle('"+MY_FOLDER+"')/items("+id+")"
Updated:
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js" type="text/javascript"></script>
<script>
$(document).ready(function () {
UpdateFolder()
function UpdateFolder(){
$.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/GetByTitle('Doc')/items(30)",
type: "POST",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"content-Type": "application/json;odata=verbose",
"IF-MATCH": "*",
"X-HTTP-Method": "MERGE"
},
data: "{__metadata:{'type':'SP.Data.DocItem'},test:'test'}",
/*where Title is column name and add your desired new data*/
success: function(data) {
console.log(data);
},
error: function(error) {
alert(JSON.stringify(error));
}
});
}
})
</script>

Related

What is the payload to be sent for "ViewFields" parameter as part of consuming the SPO REST API?

I am trying to create a SharePoint list view through the SharePoint REST API, with a defined set of columns to be part of the view. The endpoint i am using is below:
POSTMAN API Request:
HTTP METHOD: POST
URL: https://tenantname.sharepoint.com/sites/SPSite/_api/web/lists/getbytitle('ListName')/views
Headers:
'Accept' - 'application/json;odata=verbose'
'Content-Type' - 'application/json;odata=verbose'
Body (JSON):
{
"__metadata":{
"type":"SP.View"
},
"Title":"TestView",
"ViewFields":["Title","Name"]
}
I get a JSON error, since this payload does not seem to be right. Need help in understanding how to create a view with specific fields through the SharePoint REST API.
Thanks,
Yesh
When creating view, it's not supported to add viewFields, this needs to be done after creating list view.
So please create the view like this firstly:
var viewQuery = "<OrderBy><FieldRef Name=\"ID\" /></OrderBy>";
$.ajax
({
// _spPageContextInfo.webAbsoluteUrl - will give absolute URL of the site where you are running the code.
// You can replace this with other site URL where you want to apply the function
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('MyList')/views",
type: "POST",
data: "{'__metadata':{'type': 'SP.View'},'ViewType': 'HTML','Title':'New View Created From REST','PersonalView':false,'ViewQuery':'" + viewQuery + "'}",
headers:
{
// Accept header: Specifies the format for response data from the server.
"Accept": "application/json;odata=verbose",
//Content-Type header: Specifies the format of the data that the client is sending to the server
"Content-Type": "application/json;odata=verbose",
// X-RequestDigest header: When you send a POST request, it must include the form digest value in X-RequestDigest header
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: function (data, status, xhr) {
alert(data.d.Id);
},
error: function (xhr, status, error) {
console.log("Failed");
}
});
Then set Viewfield for the new created List View like this:
$.ajax
({
// _spPageContextInfo.webAbsoluteUrl - will give absolute URL of the site where you are running the code.
// You can replace this with other site URL where you want to apply the function
url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getByTitle('MyList')/Views(guid'58cfaaa2-107c-4a94-8490-38d1df195e5b')/ViewFields/addviewfield('Created')",
type: "POST",
headers:
{
// Accept header: Specifies the format for response data from the server.
"Accept": "application/json;odata=verbose",
//Content-Type header: Specifies the format of the data that the client is sending to the server
"Content-Type": "application/json;odata=verbose",
// X-RequestDigest header: When you send a POST request, it must include the form digest value in X-RequestDigest header
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: function (data, status, xhr) {
console.log("Success");
},
error: function (xhr, status, error) {
console.log("Failed");
}
});
So the above sample is adding "Created" field into viewFields and View Guid is alert in first rerquest, use it in second request.

How do I upload a custom playlist cover image with Spotify API

I'm on a private node.js project.
On the server there should be an endpoint to update the cover image of a specific playlist. Inside this endpoint I've got this code:
let playlistID = '7fOfY.......G5RFK3z'; // ID of already created playlist
let imgFile = '/9j/4AAQSkZJRg.......AgICAg'; // data:image/jpeg;base64
let spotifyAccessToken = 'DHdhw3.......DHdfLS8'; // valid access token
let options = {
url: 'https://api.spotify.com/v1/playlists/' + playlistID + '/images',
headers: {
'Authorization': 'Bearer ' + spotifyAccessToken,
'Content-Type': 'image/jpeg'
},
body: imgFile
}
request.put(options,(error, response) => {
if(response.statusCode === 202) {
console.log('Upload cover');
} else {
console.log(JSON.stringify(response));
}
In the terminal it always fails and there is no cover image in Spotify. Anyone knows what is wrong? What can I do to fix this problem? https://developer.spotify.com/documentation/web-api/reference/playlists/upload-custom-playlist-cover/
EDIT:
Response object looks like this:
{"statusCode":400,
"body":{
"error": {
"status": 400,
"message": "Bad request."
}
},
"headers":{
"content-type": "application/json; charset=utf-8",
"cache-control": "private",
"max-age=0",
"access-control-allow-origin":"*",
"access-control-allow-headers":"Accept, App-Platform, Authorization, Content-Type, Origin, Retry-After, Spotify-App-Version, X-Cloud-Trace-Context",
"access-control-allow-methods":"GET, POST, OPTIONS, PUT, DELETE, PATCH",
"access-control-allow-credentials":"true",
"access-control-max-age":"604800",
"content-length":"72",
"date":"Fri, 24 Jan 2020 09:29:49 GMT",
"via":"1.1 google",
"alt-svc":"clear",
"connection":"close"
},
"request":{
"uri":{
"protocol":"https:",
"slashes":true,
"auth":null,
"host":"api.spotify.com",
"port":443,
"hostname":"api.spotify.com",
"hash":null,
"search":null,
"query":null,
"pathname":"/v1/playlists/7fOf.....FK3z/images",
"path":"/v1/playlists/7fOf.....FK3z/images",
"href":"https://api.spotify.com/v1/playlists/7fOf.....FK3z/images"
},
"method":"PUT",
"headers":{
"Authorization":"Bearer BQDBBS2T......CZVtcz70",
"Content-Type":"image/jpeg",
"content-length":0}
}
}
https://www.base64decode.org/ which I found from this post may be useful to ensure your payload is decoding correctly to an image, you can put the base64 string in a text file and upload it to this site to see if it decodes to your desired image.
Omitting "data:image/jpeg;base64," from the start of the base64 string, if you haven't done so already, may also help.
I got the same 404 Bad Request and couldn't find out why for like 2h.. Turns out I had a \n at the end of the body text, because I imported the base64 data from a text editor that seems to add a \n automatically on save.
The body text must be without the proceeding data:image/jpeg;base64,.
I really struggle several hours to do this with axios and fetch but the base64 strings I was getting with them were not a valid one.
I then tried to use an old trick with the native XMLHttpRequest and everything works fine now. I'm downloading pictures from Spotify before uploading them to new playlist.
// Legacy code not optimized used to gather Spotify cover img in valid base64 format
function getEncodedPictureFromURL(url, uploadCallback) {
const xhRequest = new XMLHttpRequest()
xhRequest.onload = function () {
const reader = new FileReader()
reader.onloadend = function () {
uploadCallback(reader.result)
}
reader.readAsDataURL(xhRequest.response)
}
xhRequest.open('GET', url)
xhRequest.responseType = 'blob'
xhRequest.send()
}
export default {
async updatePlaylistCover(playlistId, coverUrl) {
const callback = (base64cover) => {
// Spotify does not need leading data type
const bytesNoMetadata = base64cover.split(',')[1]
// Axios object already knowing Spotify base URL and access token in the headers
request.put(`playlists/${playlistId}/images`, bytesNoMetadata, {
headers: { 'Content-Type': 'image/jpeg' }
})
}
getEncodedPictureFromURL(coverUrl, callback)
}
}
// ex
// await getEncodedPictureFromURL("PLAYLIST_ID", "https://i.scdn.co/image/ab67706c0000bebb992c70080d1de4f43fc55708")

How to get ListURL from Create Document Library response?

When I create document library in SharePoint via Client REST APIs I get different fields to identify library (like Title, EntityTypeName, Id). Sample response when I create library named "Школьные материалы 2.":
{
"d": {
"__metadata": {
"id": "https://somesite.sharepoint.com/sites/Team_49de5296/_api/Web/Lists(guid'd94587ec-ff65-4b61-b0e8-2a00513494ee')"
…
},
…
"DocumentTemplateUrl": "/sites/Team_49de5296/2/Forms/template.dotx",
…
"EntityTypeName": "2",
"Id": "d94587ec-ff65-4b61-b0e8-2a00513494ee",
"ParentWebUrl": "/sites/Team_49de5296",
"Title": "Школьные материалы 2."
}
}
Though when I go to the SharePoint portal the URL for the library is https://somesite.sharepoint.com/sites/Team_49de5296/2/Forms/AllItems.aspx. Platform that I use supports only listUrls and for my library it is "/sites/Team_49de5296/2". How can I get it from the Create Document Library Response? Should I do separate query to get it? What property would it be?
Yes, its not available in the Created list response.
But you can get it from a deferred property called RootFolder which will have a URL to make that request . It is not available by default for performance reasons.
So, you can modify from below sample code:
var siteUrl = _spPageContextInfo.webAbsoluteUrl;
var fullUrl = siteUrl + "/_api/web/lists";
$.ajax({
url: fullUrl,
type: "POST",
data: JSON.stringify({
'__metadata': { 'type': 'SP.List' },
'BaseTemplate': 100,
'Title': "Test JS List"
}),
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: function(data){
console.log(data);
// get the RootFolder endpoint
var listRootFolderEndpoint = data.d.RootFolder["__deferred"]["uri"];
$.getJSON(listRootFolderEndpoint, function( rootFolderListData ) {
// Make a GET request and then get data
console.log(rootFolderListData);
var listServerRelativeUrl = rootFolderListData.ServerRelativeUrl);
});
},
error: function(data){
console.log(data);
}
});?

Sharepoint View list

I have several lists in SharePoint, and each list has a number of views
How can I get view list items with value in SharePoint using REST API?
Can I get this data through CSOM?
When I use this method, I have this output :
http://win-lfl4bgulf29/_api/lists/getbytitle('EvertList')/views
But I'm looking for that
You can use the Endpoint like below to view list item data:
_spPageContextInfo.siteAbsoluteUrl + "/_api/web/lists/getbyTitle('EvertList')/items"
Ajax call like this:
$.ajax({
url: _spPageContextInfo.siteAbsoluteUrl + "/_api/web/lists/getbyTitle('Cars')/items",
type: "GET",
contentType: "application/json;odata=verbose",
headers: {
"Accept": "application/json;odata=verbose"
},
success: function (data) {
console.log(data.d.results);
},
error: function (data) {
alert("Error");
}
});
Responsed Json in Console:

SharePoint 2010 REST API JQUery Insert, Update, Delete

Can anyone explain or point me to a link with samples of doing Update, Delete using Jquery with the SharePoint 2010 Rest API?
I have the insert working and of course queries since the MSDN documentation explains and every tutorial on the net explains queries but just wondering if anyone ever inserts, updates, deletes data instead of only samples and tutorials on querying? Yes I know I can use the CSOM but I want to learn how this is done via jquery and sharepoint rest?
Also I want to use Merge for updating.
Here's the working insert code:
function insertMilestone() {
var mileStonesListUrl = "/_vti_bin/listdata.svc/Milestones";
var milestone = {};
milestone.Title = "Testing from REST";
var entry = JSON.stringify(milestone);
$.ajax({
type: "POST",
url: mileStonesListUrl,
data: entry,
contentType: "application/json; charset=utf-8",
error: function (xhr) {
alert(xhr.status + ": " + xhr.statusText);
},
success: function () {
getAll();
}
});
}
How to perform CRUD operations using SharePoint 2010 REST Interface
Create
In order to perform a Create operation via REST, you must perform the following actions:
Create an HTTP request using the POST verb.
Use the service URL of the list to which you want to add an entity as
the target for the POST.
Set the content type to application/json.
Serialize the JSON objects that represent your new list items as a
string, and add this value to the request body
JavaScript example:
function createListItem(webUrl,listName, itemProperties, success, failure) {
$.ajax({
url: webUrl + "/_vti_bin/listdata.svc/" + listName,
type: "POST",
processData: false,
contentType: "application/json;odata=verbose",
data: JSON.stringify(itemProperties),
headers: {
"Accept": "application/json;odata=verbose"
},
success: function (data) {
success(data.d);
},
error: function (data) {
failure(data.responseJSON.error);
}
});
}
Usage
var taskProperties = {
'TaskName': 'Order Approval',
'AssignedToId': 12
};
createListItem('https://contoso.sharepoint.com/project/','Tasks',taskProperties,function(task){
console.log('Task' + task.TaskName + ' has been created');
},
function(error){
console.log(JSON.stringify(error));
}
);
Read
In order to perform a Read operation via REST, you must perform the following actions:
Create an HTTP request using the GET verb.
Use the service URL of the list item to which you want to add an
entity as the target for the GET.
Set the content type to application/json.
JavaScript example:
function getListItemById(webUrl,listName, itemId, success, failure) {
var url = webUrl + "/_vti_bin/listdata.svc/" + listName + "(" + itemId + ")";
$.ajax({
url: url,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
success(data.d);
},
error: function (data) {
failure(data.responseJSON.error);
}
});
}
Usage
getListItemById('https://contoso.sharepoint.com/project/','Tasks',2,function(taskItem){
console.log(taskItem.TaskName);
},
function(error){
console.log(JSON.stringify(error));
}
);
Update
To update an existing entity, you must perform the following actions:
Create an HTTP request using the POST verb.
Add an X-HTTP-Method header with a value of MERGE.
Use the service URL of the list item you want to update as the target
for the POST
Add an If-Match header with a value of the entity’s original ETag.
JavaScript example:
function updateListItem(webUrl,listName,itemId,itemProperties,success, failure)
{
getListItemById(webUrl,listName,itemId,function(item){
$.ajax({
type: 'POST',
url: item.__metadata.uri,
contentType: 'application/json',
processData: false,
headers: {
"Accept": "application/json;odata=verbose",
"X-HTTP-Method": "MERGE",
"If-Match": item.__metadata.etag
},
data: Sys.Serialization.JavaScriptSerializer.serialize(itemProperties),
success: function (data) {
success(data);
},
error: function (data) {
failure(data);
}
});
},
function(error){
failure(error);
});
}
Usage
var taskProperties = {
'TaskName': 'Approval',
'AssignedToId': 12
};
updateListItem('https://contoso.sharepoint.com/project/','Tasks',2,taskProperties,function(item){
console.log('Task has been updated');
},
function(error){
console.log(JSON.stringify(error));
}
);
Delete
To delete an entity, you must perform the following actions:
Create an HTTP request using the POST verb.
Add an X-HTTP-Method header with a value of DELETE.
Use the service URL of the list item you want to update as the target
for the POST
Add an If-Match header with a value of the entity’s original ETag.
JavaScript example:
function deleteListItem(webUrl, listName, itemId, success, failure) {
getListItemById(webUrl,listName,itemId,function(item){
$.ajax({
url: item.__metadata.uri,
type: "POST",
headers: {
"Accept": "application/json;odata=verbose",
"X-Http-Method": "DELETE",
"If-Match": item.__metadata.etag
},
success: function (data) {
success();
},
error: function (data) {
failure(data.responseJSON.error);
}
});
},
function (error) {
failure(error);
});
}
Usage
deleteListItem('https://contoso.sharepoint.com/project/','Tasks',3,function(){
console.log('Task has been deleted');
},
function(error){
console.log(JSON.stringify(error));
}
);
Please follow List Items manipulation via REST API in SharePoint 2010 article for a more details.
Here is the update and delete, it wasn't as hard as I thought it was going to be and it works.
Hopefully this will help someone out because there is so much bogus information on using the REST API and I see a zillion posts on querying but none on Insert, Update, Delete.
//update
function updateMilestone(id) {
var mileStonesUrl = "/_vti_bin/listdata.svc/Milestones";
mileStonesUrl = mileStonesUrl + "(" + id+ ")";
var beforeSendFunction;
var milestoneModifications = {};
milestoneModifications.Title = "Updated from REST";
var updatedMilestoneData = JSON.stringify(milestoneModifications);
//update exsiting milestone
beforeSendFunction = function (xhr) {
xhr.setRequestHeader("If-Match", "*");
// Using MERGE so that the entire entity doesn't need to be sent over the wire.
xhr.setRequestHeader("X-HTTP-Method", 'MERGE');
}
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
processData: false,
beforeSend: beforeSendFunction,
url: mileStonesUrl,
data: updatedMilestoneData,
dataType: "json",
error: function (xhr) {
alert(xhr.status + ": " + xhr.statusText);
},
success: function () {
alert("Updated");
getAll();
}
});
function deleteMilestone(id) {
var mileStonesUrl = "/_vti_bin/listdata.svc/Milestones";
mileStonesUrl = mileStonesUrl + "(" + id+ ")";
$.ajax({
type: "DELETE",
contentType: "application/json; charset=utf-8",
processData: false,
url: mileStonesUrl,
error: function (xhr) {
alert(xhr.status + ": " + xhr.statusText);
},
success: function () {
alert("deleted");
getAll();
}
});
}
}
I recently worked with the REST API for SP 2013, as a Example POC that can be used for any call implementation i.e. JQuery, C# etc.
Using POSTMAN
First get your digest token:
A method was found on this site : http://tech.bool.se/basic-rest-request-sharepoint-using-postman/​
[Credit where credit is due]
POST
http://<SharePoint Domain Url>/sites/<Site name>/_api/contextinfo
Header:
Accept : application/json;odata=verbose
Body:
Clear the body ​
From the payload use "FormDigestValue" value and put it into your headers with the key : X-RequestDigest when making actions that alter items in SharePoint.
Reading data:
GET
http://<SharePoint Domain Url>/sites/<Site name>/_api/web/getfolderbyserverrelativeurl('/Sites/<Site Name>/Shared Documents/My Folder')/files?$select=Name
Headers:
Accept : application/json;odata=verbose​
When it comes to create, update , delete you need the digest token or an authorization token to perform these actions, this token is highlighted at the begining to to retrieve.
​Creating Data
POST
http://<SharePoint Domain Url>/sites/<Site Name>/_api/web/folders​
Headers:
Accept : application/json;odata=verbose
X-RequestDigest : 'GUID looking toking'
Content-Type : application/json;odata=verbose
Body:
{ '__metadata': { 'type': 'SP.Folder' }, 'ServerRelativeUrl': '/Sites/<Site Name>/Shared Documents/Some Folder/POC3'}​
Note:
'ServerRelativeUrl' the folder on the end POC3 is the folder that I want to create
Related resources:
http://msdn.microsoft.com/en-us/library/office/fp142380(v=office.15).aspx
Note: PostMan was used for this example and other application may need you to url encode the endpoint.
The above Request Structure can be used for all requests, the related resource highlights some of the standard methods that can be used with the REST Api

Resources