Jamgreen Jamgreen - 2 months ago 15
Javascript Question

Function only returns on events

I am calling a function with

console.log(openDialog())
and
openDialog()
creates a modal window and the function only returns on certain events.

My
openDialog()
is like

function openDialog() {
// do some html

//
buttonElement.onclick = function () {
return 'some value';
}
}


the problem is that when I call
console.log(openDialog())
, it automatically sees that my function doesn't return a value, so it just returns
undefined
. I want it to wait until my function
openDialog()
has returned something.

Maybe it's promises?

Edit



Is it just like this with callback?

function openDialog(cb) {
// do some html

buttonElement.onclick = function () {
return cb('some value');
}
}

console.log(openDialog(function (value) {
return value;
});

Answer

So, supposing you're trying to create a customized prompt(), you have to keep in mind that we cannot do it synchronous.

This uses the native prompt function which is synchronous:

var result = prompt("What's your name");

You cannot create a function like that. Instead you need to make it asynchronous: using callbacks (or promises).

Simple callback interface

function openDialog(buttonElement, cb) {
  buttonElement.onclick = function () {
    cb('some value');
  }
}

// Open the dialog
openDialog(document.querySelector("button"), function (result) {
  // After getting the result, this will be called
  alert(result);  
});
<button>Submit</button>

Promise interface

function openDialog(buttonElement) {
  var resolve = null;
  var promise = new Promise(function (_resolve) {
    resolve = _resolve;
  });
  buttonElement.onclick = function () {
    resolve('some value');
  }
  return promise;
}

// Open the dialog
openDialog(document.querySelector("button")).then(function (result) {
  // After getting the result, this will be called
  alert(result);  
});
<button>Submit</button>


If you want to send errors in the callback as well, you just have to call the callback function with an error as first argument. In the Promises case, use the reject function:

function openDialog(buttonElement) {
  var resolve = null;
  var reject = null;
  var promise = new Promise(function (_resolve, _reject) {
    resolve = _resolve;
    reject = _reject;
  });
  buttonElement.onclick = function () {
    var name = your_name.value;
    if (!name) {
      return reject(new Error("Please enter a name in the input."));
    }
    resolve(name);
  }
  return promise;
}

// Open the dialog
openDialog(document.querySelector("button")).then(function (result) {
  // After getting the result, this will be called
  alert(result);  
}).catch(function (err) {
  alert(err.message);
});
<input id="your_name" />
<button>Submit</button>

For callback situation, just call cb(null, name) for success and cb(new Error("Please enter a valid name")) for error. Then you will call it like this:

openDialog(document.querySelector("button"), function (err, result) {
  if (err) { return alert(err.message); }
  // After getting the result, this will be called
  alert(result);  
});
Comments