3

In SharePoint 2013/SharePoint online using client side rendering (CSR), I am trying to remove rows from List view webpart (LVWP). I am using OnPreRender event of CSR as below:-

(function () { 

var bodyFieldContext = {}; 
bodyFieldContext.Templates = {}; 
bodyFieldContext.OnPreRender = listPreRender;    

  SPClientTemplates.TemplateManager.RegisterTemplateOverrides(bodyFieldContext); 

})(); 

function listPreRender(ctx)
{   
    var baseURL = _spPageContextInfo.webAbsoluteUrl;        
    $.ajax({
                url: baseURL  + "/_api/Web/CurrentUser?$select=Id",
                method: "GET",                    
                headers: { "Accept": "application/json; odata=verbose" },
                success: function (data) { 
                //Below two lines have no effect here and no error is thrown                    
                    var rows = ctx.ListData.Row;               
                    rows.splice(1, 1);  
                },
                error: function (error) {
                    alert("error");
                }
            });
                //UnComment below two lines of script, these will hide the row
                //THIS WORKS OUTSIDE OF AJAX REQUEST.BUT NOT INSIDE "SUCCESS" FUNCTION ABOVE                     
                /*var rows = ctx.ListData.Row;             
                rows.splice(1, 1);*/ 
}

The issue is that removing rows form LVWP only works out side of AJAX request, not inside (Marked by comments in code above).

Any Idea why it doesn’t execute inside, but same lines of script works outside? And how to make it work from inside of AJAX call?

The reason I have to make AJAX requests is because, I need to remove rows from current LVWP, based on values in another list. Because List A and List B has no direct common field.

In List view webpart JSLink I gave the URL of above script file:- ~site/SiteAssets/Code/FilterEmployeesCSR.js

Thanks,

2 Answers 2

3

ctx is a global object,

Since JavaScript passes objects by reference the ctx inside your success function is not a locally scoped variable.

So after you initiated the Ajax call (its asynchronous!), your CSR code immediatly continues, and does all sort of things with the global ctx

It might well be all CSR overrides AND PostRender have executed in the meantime.

Then your success function deals with a global ctx that is not the same state as was passed to the lisPreRender function.

Making your Ajax call synchronous with async:false is a solution because your code doesn't continue until the success function has run

Alternative is to execute the Ajax call first and do all the CSR stuff in the success callback.

or

all this jQuery stuff returns a Promise by default, and are much easier to read

So you can ditch the succces and error callbacks and do

$.ajax({
  url: baseURL  + "/_api/Web/CurrentUser?$select=Id",
  method: "GET",                    
  headers: { "Accept": "application/json; odata=verbose" }        
}).then(function(data){
 //do your CSR stuff here
}).fail(function(e){
 //error
});

for more explanation and a no-jQuery solution see: REST call to get list not working

This does not block like async:false does, in your case it does not make a difference; if the code gets more complex and does more ajax calls it does make a difference.

1

Your code does not wait for the ajax call to complete. It is executed before the completion of ajax call. That is the reason your ajax code is not working. Setting async:false inside the ajax call will make it work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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