Link to home
Start Free TrialLog in
Avatar of Isaac
IsaacFlag for United States of America

asked on

JSOM - update metadata of existing document in a document library

I have a document library and I would like to update the metadata(columns) of a document using JSOM.  I thought the following would work but it works just on custom library.

 var ctx = new SP.ClientContext.get_current();
                            var customList = ctx.get_web().get_lists().getByTitle('Shared Documents');
                            var listItem = customList.getItemById(itemID);

                            /*Set the value and update*/
                            listItem.set_item('Project_0020_Number', prjNum);
                            listItem.update();

                            ctx.executeQueryAsync(
                            function(){ 
                                                                            /*Need to change this to show on the page*/
                                                                            alert('Updated'); 
                                            }, 

                                            function(sender, args){ alert('Error: ' + args.get_message()); });
                                            }

                                            function onQueryFailed(sender, args) {
                                                            alert('Request failed. '+args.get_message() + '\n' + args.get_stackTrace());

Open in new window

Avatar of Jamie McAllister
Jamie McAllister
Flag of Switzerland image

If it works on a custom library it probably works.

Whats the score with that column name Project_0020_Number? Is the column name the same in Shared Documents?
Avatar of Isaac

ASKER

My apologies, I meant it works on custom lists but not on a document library.  "Project_0020_Number" is the name of the column in my document library
Avatar of Isaac

ASKER

Here's the error I get:

Here's the error I get "Request failed. List 'Shared Documents' does not exist at site with URL 'http://isogunro.com/nrm. undefined"
Code looks fine.

Is the list in the web the error message mentions?

Is that url correct for the SPWeb instance?

Do you have a library without spaces in name to test against?
Avatar of Isaac

ASKER

I figured out that I need to modify the following line with the column that I need to update.

        var body = String.format("{{'__metadata':{{'type':'{0}'}},'FileLeafRef':'{1}','Title':'{2}','Project_0020_Number':'{3}'}}",
            itemMetadata.type, newName, newName,projNum);

Open in new window


I get the following error:
<?xml version="1.0" encoding="utf-8"?><m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><m:code>-1, Microsoft.SharePoint.Client.InvalidClientQueryException</m:code><m:message xml:lang="en-US">The property 'Project_0020_Number' does not exist on type 'SP.Data.Shared_x0020_DocumentsItem'. Make sure to only use property names that are defined by the type.</m:message></m:error>


Project_0020_Number is the internal name of the column I need to update
Avatar of Isaac

ASKER

I'm sorry, I found another solution that worked but I am unable to update a certain column.  Here's the code

'use strict';

jQuery(document).ready(function () {

    // Check for FileReader API (HTML5) support.
    if (!window.FileReader) {
        alert('This browser does not support the FileReader API.');
    }
    
   });

// Upload the file.
// You can upload files up to 2 GB with the REST API.
function uploadFile() {
//alert("HELLO");
    // Define the folder path for this example.
    var serverRelativeUrlToFolder = 'Shared Documents';

    // Get test values from the file input and text input page controls.
    var fileInput = jQuery('#getFile');
    var newName = jQuery('#displayName').val();
	//alert("fileInput: "+fileInput);
	//alert("newName: "+newName);
    // Get the server URL.
    var serverUrl = _spPageContextInfo.webAbsoluteUrl;

    // Initiate method calls using jQuery promises.
    // Get the local file as an array buffer.
    var getFile = getFileBuffer();
    getFile.done(function (arrayBuffer) {

        // Add the file to the SharePoint folder.
        var addFile = addFileToFolder(arrayBuffer);
        addFile.done(function (file, status, xhr) {
            // Get the list item that corresponds to the uploaded file.
            var getItem = getListItem(file.d.ListItemAllFields.__deferred.uri);
            getItem.done(function (listItem, status, xhr) {
            /***************************************************************************/            
            /* --------------- Update list with some of the form data -----------------*           
				if (status === "success"){
					updateLibrary(listItem.d.Id, "projNum");	
					console.log(listItem.d.Id);
					console.log(status);
					console.log(xhr);
			
				}            
             --------------- Update list with some of the form data -----------------*/
            /***************************************************************************/
                // Change the display name and title of the list item.
                var changeItem = updateListItem(listItem.d.__metadata);
                changeItem.done(function (data, status, xhr) {
                    alert('file uploaded and updated');
                });
                changeItem.fail(onError);
            });
            getItem.fail(onError);
        });
        addFile.fail(onError);
    });
    getFile.fail(onError);

    // Get the local file as an array buffer.
    function getFileBuffer() {
        var deferred = jQuery.Deferred();
        var reader = new FileReader();
        reader.onloadend = function (e) {
            deferred.resolve(e.target.result);
        }
        reader.onerror = function (e) {
            deferred.reject(e.target.error);
        }
        reader.readAsArrayBuffer(fileInput[0].files[0]);
        return deferred.promise();
    }

    // Add the file to the file collection in the Shared Documents folder.
    function addFileToFolder(arrayBuffer) {

        // Get the file name from the file input control on the page.
        var parts = fileInput[0].value.split('\\');
        var fileName = parts[parts.length - 1];

        // Construct the endpoint.
        var fileCollectionEndpoint = String.format(
                "{0}/_api/web/getfolderbyserverrelativeurl('{1}')/files" +
                "/add(overwrite=true, url='{2}')",
                serverUrl, serverRelativeUrlToFolder, fileName);
                console.log("fileCollectionEndpoint "+fileCollectionEndpoint);

        // Send the request and return the response.
        // This call returns the SharePoint file.
        return jQuery.ajax({
            url: fileCollectionEndpoint,
            type: "POST",
            data: arrayBuffer,
            processData: false,
            headers: {
                "accept": "application/json;odata=verbose",
                "X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
                "content-length": arrayBuffer.byteLength
            }
        });
    }

    // Get the list item that corresponds to the file by calling the file's ListItemAllFields property.
    function getListItem(fileListItemUri) {

        // Send the request and return the response.
        return jQuery.ajax({
            url: fileListItemUri,
            type: "GET",
            headers: { "accept": "application/json;odata=verbose" }
        });
    }

    // Change the display name and title of the list item.
    function updateListItem(itemMetadata) {
console.log(itemMetadata);
alert(itemMetadata.id);
var projNum = "Proj number 132";
        // Define the list item changes. Use the FileLeafRef property to change the display name. 
        // For simplicity, also use the name as the title. 
        // The example gets the list item type from the item's metadata, but you can also get it from the
        // ListItemEntityTypeFullName property of the list.
        var body = String.format("{{'__metadata':{{'type':'{0}'}},'FileLeafRef':'{1}','Title':'{2}','Project_0020_Number':'{3}'}}",
            itemMetadata.type, newName, newName,projNum);
console.log("body: "+body);
        // Send the request and return the promise.
        // This call does not return response content from the server.
        return jQuery.ajax({
            url: itemMetadata.uri,
            type: "POST",
            data: body,
            headers: {
                "X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
                "content-type": "application/json;odata=verbose",
                "content-length": body.length,
                "IF-MATCH": itemMetadata.etag,
                "X-HTTP-Method": "MERGE"
            }
        });
    }
}

// Display error messages. 
function onError(error) {
    console.log(error.responseText);
}

function updateLibrary(itemID, prjNum){
alert("itemID: "+itemID);
alert("proj num: "+prjNum);
/*		$().SPServices({
			operation: "UpdateListItems",
			//async: false,
			listName: "Shared Documents",
			ID: itemID,
			valuepairs: [["Project_0020_Number",prjNum]],		
		completefunc: function(xData, status){
		console.log(xData);
		console.log("status: "+status);
				//alert("Sending the xml request to the server was: " + status);
				//alert("Sharepoint processing of the message returned: " + xData.responseText);
		}
		});	*/
		
                                //var rowID = parseInt(itID);
                               var ctx = new SP.ClientContext.get_current();
								var customList = ctx.get_web().get_lists().getByTitle('Shared Documents');
								var listItem = customList.getItemById(itemID);
								
								/*Set the value and update*/
								listItem.set_item('Project_0020_Number', prjNum);
								listItem.update();
								
								ctx.executeQueryAsync(function(){
								    /*Need to change this to show on the page*/
								    alert('Updated'); 
								},function(sender, args){
								    alert('Request failed. '+args.get_message() + '\n' + args.get_stackTrace());
								});

}

Open in new window

Avatar of Isaac

ASKER

I found the solution here (Code Example 2)  This helped me with my original issue which was to upload a file but then I could not update other columns/metadata.  When I tried to, I received the error posted in my last comment.
ASKER CERTIFIED SOLUTION
Avatar of Jamie McAllister
Jamie McAllister
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Isaac

ASKER

ARGH!!  I need rest in my life.  Can't believe I missed that.  Thank you!!!
Happens to us all! :)