1

I have the following function:

var makeNewContextMenu = function( metadata, $toggle, $after){
    dataStore.getCollaboration(metadata._mountTarget).then(function(data){
      //need to access metadata, $toggle and $after inside promise
    })
}

How would I be able to access metadata, $toggle, and $after inside my promise?

user5844628
  • 397
  • 1
  • 5
  • 15

1 Answers1

2

You can just use them exactly as your code shows. Variables or arguments from a parent scope are available to an inline function like your .then() handler.

var makeNewContextMenu = function( metadata, $toggle, $after){
    dataStore.getCollaboration(metadata._mountTarget).then(function(data){
       // this works!
       console.log(metadata);
       console.log($toggle);
       console.log($after);
    })
}

The only reason you might not be able to access a variable or argument defined in the parent scope is if some intervening scope defines a variable or argument of the same name. In that case, the scope that is closer to you has precedence and the higher scoped variable is "hidden" by the closer scoped variable of the same name and the higher scoped variable would not be accessible without renaming one to not have the same name. But, that is not what is happening in your case.


In your comment, you asked how to get a return value that includes metadata, $toggle, $after and data. Because dataStore.getCollaboration() is asynchronous which means it's response is available sometime in the future, but makeNewContextMenu() returns immediately, you can't directly return data from makeNewContextMenu(). But, you can return a promise and make the desired data be the fulfilled value of the promise like this:

var makeNewContextMenu = function( metadata, $toggle, $after){
    return dataStore.getCollaboration(metadata._mountTarget).then(function(data){
       return {
           metadata: metadata,
           $toggle: $toggle,
           $after: $after,
           data: data
       };
    })
}

makeNewContextMenu(...).then(function(info) {
    console.log(info.metadata);
    console.log(info.$toggle);
    console.log(info.$after);
    console.log(info.data);
});

Note, you really don't have to put metadata, $toggle and $after in this returned data structure because they were passed in as arguments to makeNewContextMenu() so they are already available in the scope in which makeNewContextMenu() was called. You could just directly refer to them there and use their original variables.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Awesome! Thanks for the quick response. As a follow up question, how would I be able to return {metadata, $toggle, $after, data} when I invoke makeNewContextMenu? – user5844628 Jan 27 '16 at 03:27
  • @user5844628 - Return them from what? – jfriend00 Jan 27 '16 at 03:29
  • say I call, makeNewContextMenu. How would I be able to have makeNewContextMenu return {metadata, $toggle, $after, data} as an output – user5844628 Jan 27 '16 at 03:31
  • @user5844628 - Assuming `dataStore.getCollaboration()` is asynchronous, you can't. `data` is not available yet when `makeNewContextMenu()` returns. It will return BEFORE `dataStore.getCollaboration()` has called its callback so `data` is not yet known. You can return the promise and use the returns promise. I will add how to do that to my answer. – jfriend00 Jan 27 '16 at 03:42