Question

Is there a way to dynamically create a REST call and specifically I am referring to the data: section of the call. If I get the terminology incorrect by all means keep me honest. I tried some things with no success. I looked at the __metadata portion and thought this was a key/value pair and tried some substitution with no luck. Same for the field:value pairs. Been poking around on stack to try to find something with no luck so far.

So, in the following REST example is there a way to "break out" the information following the __metadata in the brackets and also the field:value immediately after the brackets.

    $.ajax({
    type: 'POST',
    url: odataUrl, 
    contentType: "application/json;odata=verbose",
    processData: false,
    headers: {
            "Accept": "application/json;odata=verbose",
            "Content-Type":"application/json;odata=verbose",
            "X-RequestDigest":$("#__REQUESTDIGEST").val(),
            //"If-Match": "*", 
            //"X-HTTP-Method": "MERGE"
    },
              
    data: JSON.stringify(
        {
        __metadata :{
            **"type":"SP.Data.ErrorHandlerListItem"
        },
        Title:"TEST",
        ver:'2.0',
        modname:'no name'**
        

    }),

I tried using the following with no luck as an example setting the variables outside the REST statement and replacing the metadata statement with the following vars.

var typetest={"type":"SP."+TargetListName+"ListItem"};
var savetst={Title:"projname",ver:'test',modname:'browsertest'};
     data: JSON.stringify(
         {
          __metadata :{typetest},savetxt

Thanks for the help.

Was it helpful?

Solution

You are getting pretty close. Yes, you definitely can use variables to make certain parts of the data that you send to SharePoint dynamic.

First. let me point out a couple errors I see in the way you have structured your first attempt there:

var typetest={"type":"SP."+TargetListName+"ListItem"};
var savetst={Title:"projname",ver:'test',modname:'browsertest'};

// i am assuming the above lines are not actually inside the
// ajax call, and you were just showing appreviated code

     data: JSON.stringify({
          __metadata :{typetest},savetxt
         })

If we break down what you have inside the JSON.stringify() function, and "fill in" what you have defined in the variables, you get

JSON.stringify({
    __metadata: {
            { "type": "SP."+TargetListName+"ListItem" } // notice you end up with double curly braces here
        },
        {                       // and you end up with curly braces here, after the comma after "__metadata", instead of just straight key/value pairs
            Title:"projname",
            ver:'test',
            modname:'browsertest'
        }
})

Also, in the first example, for the metadata type you have

"SP.Data.ErrorHandlerListItem"

while in your "dynamic" version you have

"SP."+TargetListName+"ListItem"

which would really end up as "SP.ErrorHandlerListItem", which is missing that .Data. part, so you really want

"SP.Data." + TargetListName + "ListItem"

That all being said, the way I would make this easier to work with is to not put the data payload object inline with the JSON.stringify() function, but to make it it's own separate object in a variable, like this

var payload = {
    __metadata :{
        "type":"SP.Data.ErrorHandlerListItem"
    },
    Title:"TEST",
    ver:'2.0',
    modname:'no name'
};

$.ajax({
    type: 'POST',
    url: odataUrl, 
    contentType: "application/json;odata=verbose",
    processData: false,
    headers: {
            "Accept": "application/json;odata=verbose",
            "Content-Type":"application/json;odata=verbose",
            "X-RequestDigest":$("#__REQUESTDIGEST").val(),
            //"If-Match": "*", 
            //"X-HTTP-Method": "MERGE"
    },
    data: JSON.stringify(payload)
});

Then you can start to do things like

function getMetadataTypeValue (listName) {
    // you can do more sophisticated stuff in here
    // like deal with spaces in the list name
    return "SP.Data." + listName + "ListItem";
}

var titleValue = "TEST";  // or some other way of dynamically generating this
var versionValue = "2.0"; // or dynamically determined
var modValue = "no name"; // etc

var payload = {
    __metadata: {
        "type": getMetadataTypeValue(dynamicTargetListName)
    },
    Title: titleValue,
    ver: versionValue,
    modname: modValue
}

Also, JavaScript is very forgiving, and you can add properties to an object dynamically just by defining it using dot notation on the fly. So you can start with:

var payload = {
    __metadata: {
        "type": "SP.Data." + listName + "ListItem" // assume listName = "ErrorHandler"
    }
}

Now your original payload object is only

{  __metadata: {
     "type": "SP.Data.ErrorHandlerListItem"
   }
}

but then you can do something like

var needToAddTitle = true;
var titleValue = "Updated Title";

if (needToAddTitle) {
    payload.Title = titleValue;
}

Now your payload object is

{  __metadata: {
     "type": "SP.Data.ErrorHandlerListItem"
   },
   Title: "Updated Title"
}

but if needToAddTitle = false and the line payload.Title = titleValue is never executed, then the payload object is still

{  __metadata: {
     "type": "SP.Data.ErrorHandlerListItem"
   }
}

because you never defined payload.Title = something.

In that way you can dynamically build up each of the properties you need on the payload object, and not only dynamically add each property as needed, but use variables to set the property values, or even call functions to dynamically generate (and return) the property values.

Then, once your payload is set up the way you want, then you do your ajax call, passing the payload variable/object into the JSON.stringify() function:

$.ajax({
    type: 'POST',
    url: odataUrl, 
    contentType: "application/json;odata=verbose",
    processData: false,
    headers: {
            "Accept": "application/json;odata=verbose",
            "Content-Type":"application/json;odata=verbose",
            "X-RequestDigest":$("#__REQUESTDIGEST").val(),
            //"If-Match": "*", 
            //"X-HTTP-Method": "MERGE"
    },
    data: JSON.stringify(payload)
});
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top