1

I have a basic function in protractor written as :

this.getCurrentUrl = function () {
    browser.getCurrentUrl().then(function(url){
        console.log('url : '+url);
    });
};

Now is there a way I can access the 'url' outside of the inner function scope, because I need to return this value to some other function calling this one. I need to get the value and return it from outside of then(function(url){...}

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • 1
    I seriously suspect that real question is duplicate or "return value from async function"... Please confirm that that is no asynchronous code in your sample (preferably update code to remove confusing `.then(...)` if it is the case) – Alexei Levenkov May 20 '16 at 05:13
  • Protractor is itself asynchronous, so yes, it is indeed – Bishwaroop Chakraborty May 20 '16 at 05:17
  • Basically, you can't get a return value from this function if it's making an async call. Look at the links above to make the function calling this function expect an async response. – UtsavShah May 20 '16 at 05:39

1 Answers1

1

the url will be acquired async, so you can't just assign it. You probably want to hand it a callback.

function handleUrl(url) {
  // here is where you do something with the url
}

// let your callback be called
this.getCurrentUrl = function(fn) {
  browser.getCurrentUrl().then( function (url) {
    fn(url);
  }) 
}

// make the call with your handler
this.getCurrentUrl(handleUrl);

Another approach is to have your function return a "container" and that gets inflated later. Then later you can check your container. Since the behavior is async, you won't know when it will be ready, so you can check for it on an interval or something...

// return a container object
this.getCurrentUrl = function() {
    var urlContainer = {};
    browser.getCurrentUrl().then( function (url) {
      urlContainer.url = url;
    });
    return urlContainer;
}

var urlContainer = this.getCurrentUrl(); // starts off as an empty object
urlContainer.url // undefined

// then shortly in the future

urlContainer.url // has some url

Yet a third way is to return a closure

this.getCurrentUrl = function() {
   var urlValue;
   browser.getCurrentUrl().then(function(url) {
      urlValue = url;
   });
   return function() {
      return urlValue;
   }
}

var getUrl = this.getCurrentUrl(); 
getUrl(); // initially, returns undefined;

// keep trying. then shortly in the future...
getUrl(); // now has the url
Joe Hanink
  • 4,767
  • 4
  • 19
  • 21
  • so I should call getUrl() here? – Bishwaroop Chakraborty May 20 '16 at 05:58
  • the problem you facing is that the operation that obtains the url is async. Therefore, you can't simply say `var url = getCurrentUrl()`. You have to either use a callback and make your callback do something with the url OR use 2nd or 3rd approaches which will require testing the result on some interval until it has a value. – Joe Hanink May 20 '16 at 06:05