0

I have some JS methods that create site columns and add it to site content types. These are working fine if you use them once. But if I want to add a bunch of columns (within an array) it's not working:

Failed: The object has been updated by another user since it was last fetched.

Thats obvious, since I access the same content type object several times.

I also tried to use the callback of executeQueryAsync() and go recursivly through the array. But this doesn't work either. I got an Out-of-Memory-Exception.

Is there a way to execute the queries synchronously?

addFieldToContentType: function(fieldSTR, contentTypeSTR, successFUN) { 
    var clientContextOBJ = (csListBuilder.contextURL != "") ? new SP.ClientContext(csListBuilder.contextURL) : new SP.ClientContext.get_current();
    var webContextOBJ = clientContextOBJ.get_web(); 


    //get content types
    var contentTypesARY = clientContextOBJ.get_site().get_rootWeb().get_contentTypes(); 
    clientContextOBJ.load(contentTypesARY);

    clientContextOBJ.executeQueryAsync(function() {
        var numeratorOBJ = contentTypesARY.getEnumerator();
        var loopBLN = true;
        var contentTypeOBJ;

        //loop through all content types to get to our wanted one
        while (numeratorOBJ.moveNext() && loopBLN == true) {
            contentTypeOBJ = numeratorOBJ.get_current();
            loopBLN = (contentTypeOBJ.get_name() == contentTypeSTR) ? false : true;
        }   

        //Build the field Info and add it to the content type object
        var fieldOBJ = clientContextOBJ.get_site().get_rootWeb().get_fields().getByInternalNameOrTitle(fieldSTR);           
        var infoOBJ = new SP.FieldLinkCreationInformation();
        infoOBJ.set_field(fieldOBJ);

        contentTypeOBJ.get_fieldLinks().add(infoOBJ)        
        contentTypeOBJ.update();

        clientContextOBJ.executeQueryAsync(successFUN, function(senderOBJ, argsOBJ){
            if(csListBuilder.alertErrorsBLN) {
                alert('Failed: ' + argsOBJ.get_message());
            } else {
                console.log('Failed: ' + argsOBJ.get_message());
            }               
        });

    }, null);       
}

Recursive Approach:

function addSiteColumns(i) {
        //Recursive approach;
        console.log("Adding Column " + siteColumnsARY[i].nameSTR + " to Content Type " +  siteColumnsARY[i].contentTypeSTR);
        csListBuilder.addFieldToContentType(siteColumnsARY[i].nameSTR, siteColumnsARY[i].contentTypeSTR, function() {
            i++;                
            if (i < siteColumnsARY.length) {
                addSiteColumns(i);
            }               
        });                     
}
  • JSOM having only ExecuteQueryAsync method so we will need to do sync call for add multiple column at a same time. You can create recursive function and use counter for call function itself in success of column add in content type. – Samir Khimani Jan 18 '17 at 12:26
  • As I said: I tried that and got of memory... – Dave Jan 18 '17 at 12:33
  • you will need to use JQuery deferred for this – dsouzajoel22 Jan 18 '17 at 12:35
  • Can you please post your solution with callback? Callback and recursion is one way to do that, I tend to think you did that incorrectly. – Sergei Sergeev Jan 18 '17 at 12:44
  • Its been awhile since I did JSOM.. first thought: Are you doing operations that require the JSOM context on the page to be re-initialized? Small test: Place the second update/create in your success function; once that works make it work with the array method you tried; because that is the way to go. If you get memory errors you are doing something wrong. Post the code you tried. extra note: Use the break; statement to quit your while loop, saves that loopBLN variable and is less error prone – Danny '365CSI' Engelman Jan 18 '17 at 13:29
1

The pattern you need is something like this

pseudo code:

var myData = [1,2,3,4,5];

function addField() {
    if( myData.length>0 ){
        var addingThisOne = myData.pop();
        executeAsync( success );
    }
}

function success(){
    addField();
}

You could debate if it is recursion or not, key is that you do not pass a shitload of data around

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.