13

How can I get this function to return the value? In all the examples I have seen, folks use an alert in the delegate functions, but I need to return the value instead. When I call the function, it fetches me my default string, which means the executeQueryAsync is not setting the variable.

What am I doing wrong?

var thisuser = SPGetSPcurrentUser();
alert(thisuser);
//-------------------------------------------------------------------
var SPGetSPcurrentUser = function(){
    var spuserid = "Error";
    var context = new SP.ClientContext.get_current();
    this.website = context.get_web();
    this.currentUser = website.get_currentUser();
    context.load(currentUser);
    context.executeQueryAsync(
        function(sender, args){ this.spuserid = currentUser.get_loginName();},
        function(sender, args){ this.spuserid = 'request failed ' + args.get_message() + '\n'+ args.get_stackTrace();}
    )
    return spuserid;
}

2 Answers 2

15

As the method executeQueryAsync indicates it is asynchronous.
You can actually force the XMLHttpRequest to be synchronous, although that is beside the point.

What you are looking for is a callback function, something like this:

var getSpCurrentUser = function(callback) {
  var ctx = SP.ClientContext.get_current();
  var user = ctx.get_web().get_currentUser();

  ctx.load(user);
  ctx.executeQueryAsync(function() {
    callback(null, user);
  }, function(a, b) {
    callback(new Error(b.get_message()));
  });
};

getSpCurrentUser(function(error, user) {
  if (error) {
    console.error(error);
    return;
  }
  console.log(user.get_title());
});
9
  • 1
    Thanks, Erik. I've only ever used a callback function once or twice in my life. I don't understand where anything returns the value. Also, could you explain to me how there can be two functions with the same name? (Sorry for being dense)
    – bgmCoder
    Commented Dec 7, 2012 at 23:36
  • 1
    The value is not returned, instead you pass a function into the getSpCurrentUser as a variable (line 13 and 1, named callback) which will be called from within the getSpCurrentUser function (line 7 and 9). Since executeQueryAsync is asynchronous any code after line 19 will be run before you get your callback (line 14-18). There should not be two functions with the same name
    – eirikb
    Commented Dec 7, 2012 at 23:48
  • So the first instance of getSpCurrentUser is just a variable, and the second instance, being a callback is really just an extension of the variable? So, to actually call the callback function, I would just use "callback"?
    – bgmCoder
    Commented Dec 8, 2012 at 1:54
  • I think I don't need the executeQuery to be Async. Is there a way to return the query within the same thread? I realize that would make the script wait.
    – bgmCoder
    Commented Dec 8, 2012 at 1:55
  • 1
    With executeQueryAsync it is impossible. I believe you can do it with SPServices. See example
    – eirikb
    Commented Dec 9, 2012 at 0:44
1

This is the closest I've found to returning a variable reference for the logged-on user.

Try it out it's simple to test: 1. In IE browse to your SharePoint site, open developer tools press (f12) 2. Open the Console press (ctl + 2) 3. Switch line-mode with your cursor in the "Console input" press (ctl + alt + m) 4. Paste all the following contents into the console then press (ctl + enter)

function iWannaDoSomethingWith(thisUser){
 if(thisUser === null){
  alert('failed to get user');
 }
 else{
  alert('User name:' + thisUser.get_title() 
  + '\n Login Name:' + thisUser.get_loginName());
 }
}
function necessaryEvilToWireItAllTogether(nameOfFuncWeReallyWantToCall){
 if (typeof(nameOfFuncWeReallyWantToCall)==="function")
 {
  var ctx = new SP.ClientContext.get_current();
  var oWeb = ctx.get_web();
  var currentUser = oWeb.get_currentUser();
  currentUser.retrieve();
  ctx.load(oWeb);
  ctx.executeQueryAsync(
   function(){
    // successful Async call
    nameOfFuncWeReallyWantToCall(currentUser);
   },
   function(){
    // failed Async call
    nameOfFuncWeReallyWantToCall(null);
   }
  );    
 }
}
ExecuteOrDelayUntilScriptLoaded(function(){necessaryEvilToWireItAllTogether(iWannaDoSomethingWith);}, "sp.js");

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.