This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I have a chrome extension. Its code has a method getSelectionFromPage() which catches the text selected on the webpage and always returns true like below:
function getSelectionFromPage() {
window.selected = true;
chrome.tabs.executeScript({
code: "window.getSelection().toString();"
}, function(selection) {
if (selection[0] != '') {
window.selected = true;
}else{
window.selected = false;
}
});
return true
}
On the same window context, I ran the following commands on the console.
The result can be seen as follows:
I am writing the same commands here also:
getSelectionFromPage() //-> true
window.selected //-> false
(getSelectionFromPage() && window.selected) //-> true
The (getSelectionFromPage() && window.selected) should be false. I have tried checking typeof(window.selected) and typeof(getSelectionFromPage()) and both are returning boolean. I don't understand why it is happening.
The function which is setting to false is a callback. This will not execute until after the current execution context is complete. Therefore, it will not be set to false until after && window.selection completes execution.
executeScript docs: https://developer.chrome.com/extensions/tabs#method-executeScript
The order of things is:
(function () {
window.selected = true; // Runs
chrome.tabs.executeScript({code: "window.getSelection().toString();"}, function(){
window.selected = false;
}); // Calls browser API and set's callback (the anonymous function there) to call later)
// NOTE: the callback function which was set here was NOT executed yet it was only defined.
return true;
})() // true
&& window.selected // this is currently true
// Later, now callback executes
If you would like to wait, you could use a Promise instead.
function getSelectionFromPage() {
return new Promise(function (resolve) {
chrome.tabs.executeScript(
{code: "window.getSelection().toString();"},
// or just put resolve here instead of defining a function to get value directly
function(v){
resolve(!!v);
}
);
});
}
getSelectionFromPage().then(haveSelection => console.log(haveSelection);
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 4 years ago.
Edit: Worth to say that is not duplicate, because in the marked duplicate; none of the functions have a child function inside. so returns from child don't return to parent.
--
I have an async function inside a IIEF. Like this
$(function($){
asyncAction((result)=>{
if(result == someValidation()){
return false;
}
})
console.log("don't execute this");
});
I need the return false to be executed for the parent IIEF function (it stops a global program flow)
However, there are 2 problems:
Return false executes for child function, not for the parent (because it's a callback)
Console.log executes because the asyncAction is not stopping anything.
How can I stop parent function to stop executing after the return false fron async child?
What I've tried:
$(function($){
let resultToParent = true;
asyncAction((result)=>{
if(data == someValidation()){
resultToParent = false;
}
})
if(resultToParent == false){
return false;
}
});
But this does not work because the child async.
$(function($){
try{
asyncAction((result)=>{
if(data == someValidation()){
throw Error
}
})
}
catch(err){return false}
});
But this does not work because try/catch works for synchronous only? (not sure about this?)
--
Thanks for the help!
I have a javascript function which needs to return true in order to update the browser UI. How can I make sure the function returns before executing the code to make a backend call?
self.resortCopy = function(item) {
self.resorts.push(item);
self.backendCall(item) // this needs to be performed after returning true
return true;
I imagine you are having a ajax request inside self.backendCall (XHR/fetch)
If that is true, then your code already async
Else, look at #hemp's answer
function ajax(){
fetch("https://httpbin.org/get").then(data=>{
console.log("DONE")
})
}
function test(){
ajax();
return true;
}
console.log(test())
Assuming browser JS, you can use setTimeout universally, this will guarantee that the current codepath finishes before the backendCall code executes, but it doesn't say anything else about when (unless you specify a timeout period.)
self.resortCopy = function(item) {
self.resorts.push(item);
window.setTimeout(self.backendCall.bind(self, item), 0);
return true;
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
There are two elements on the GUI, depending on the context only a single is visible.
Therefore, i like to use a helper function that gives the the Protractor element of the currently visible element.
However, i have to wait until the promise is resolved since everything is asynchronous.
function () {
var result;
var controlA = $('controlA');
var controlB = $('controlB');
listControl.isDisplayed().then(function (isVisible) {
result = isVisible;
// STEP X
});
// WAIT HERE UNTIL STEP X is done
return result ? controlA : controlB;
};
Clarification: I do NOT want to wait until the control is getting visible.
You can directly return the control inside the isDisplayed() promise itself.Look at below example code.
function () {
var result;
var controlA = $('controlA');
var controlB = $('controlB');
return listControl.isDisplayed().then(function (isVisible) {
return isVisible ? controlA : controlB;
});
};
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
How to return value from an asynchronous callback function? [duplicate]
(3 answers)
Closed 6 years ago.
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){...}
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
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
Here there is an example code:
//IF I JUST TRY TO CONNECT TO MONGODB
function ConnectToMongo(db) {
myVar = false;
db.collection("MyCollection", function(error,collection) {
myVar = true;
});
console.log(myVar); // RETURN TRUE
}
//IF I TRY TO INSERT DATA
function InsertDataOnMongoDB(db) {
myVar = false;
db.collection("MyCollection", function(error,collection) {
collection.insert(data, function(error,result){
myVar = true;
});
});
return myVar; // RETURNS FALSE!!
}
How can I execute the last line line "return myVar" only after collection.insert function ends? I need to return true, in this case.
Thank you!
It displays false because these two functions before console.log are asynchronous. For this reason console.log is executed while db.collection and collection.insert are still executing, so myVar = true; starts when these two operations have finished.
In order to see "true" you have to insert your console.log straight after myVar = true;
This way:
db.collection("MyCollection", function(error, collection){
collection.insert(data, function(error, result){
myVar = true;
console.log(myVar);
});
});