1

Confused about getting result from another function.

Clicking in button I need the value of dgInput - if Enter on keyboard is pressed.

$('button').on('click', function() {
  let str = fn();
  console.log(str);
});

function fn() {
  $('#dgInput').show().focus();
  $('#dgInput').on('keypress', function(e) {
    if (e.keyCode == 13) {
      return ($('#dgInput').val());
    }
  });
}
#dgInput {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button>CLICK</button>
<br><br>
<input type='text' id='dgInput'>
mplungjan
  • 134,906
  • 25
  • 152
  • 209
  • 2
    Possible duplicate of [*How do I return the response from an asynchronous call?*](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) (?) (Not 100% sure, but probably 80%... :-) ) – T.J. Crowder Dec 30 '18 at 08:35
  • Possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – FZs Jun 17 '19 at 06:30

3 Answers3

1

This is an X/Y problem in my opinion

If you want to show an input after the button is pressed, show it. You can still assign a handler to it without it being visible

For a non-kiss solution, see the answer with the promise.

$('#dgInput').on('keypress', function(e) {
  if (e.keyCode == 13) {
    console.log($('#dgInput').val());
  }
});

$('button').on('click', function() {
  $('#dgInput').show().focus();
});
#dgInput {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button>CLICK</button>
<br><br>
<input type='text' id='dgInput'>
mplungjan
  • 134,906
  • 25
  • 152
  • 209
  • this is not `xy` problem but the problem of getting the value `if` Enter is pressed - by clicking on a button. –  Dec 30 '18 at 08:49
  • 1
    @puerto This is what he meant by it being an XY problem: https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – Herohtar Dec 30 '18 at 09:07
0

fn can't return the value, since when fn returns, the user hasn't pressed Enter yet and so the value isn't available yet. (See this question's answers for more on that.)

You could have fn return the promise of the value, and then have the calling code consume that promise:

$('button').on('click', function() {
  // Prevent repeated clicks
  this.disabled = true;
  fn()
    .then(str => {
      console.log(str);
    })
    .catch(error => {
      console.log("Didn't get a value");
    })
    .finally(() => {
      // Allow clicks again
      this.disabled = false;
    });
});

function fn() {
  return new Promise((resolve, reject) => {
    var dgInput = $('#dgInput');
    dgInput.show().focus();
    dgInput.on('keypress', function(e) {
      if (e.keyCode == 13) {
        dgInput.off('keypress');
        dgInput.hide();
        resolve(dgInput.val());
      }
    });
    // Perhaps some event for the user not doing it, which would call `reject`
  });
}
#dgInput {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button>CLICK</button>
<br><br>
<input type='text' id='dgInput'>
T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639
  • As always, your answer is concise, insightful, and practical, but it might be worth mentioning, or at least linking to, approaches leveraging observable abstractions. Despite that they are never likely to see standardization, this is one of the rather rare cases where they actually solve my problems than they introduce in JavaScript. – Aluan Haddad Dec 30 '18 at 08:44
  • @puerto - You don't necessarily, but what if the user never presses Enter? How long do you want the code to wait? :-) You might consider a timeout. – T.J. Crowder Dec 30 '18 at 08:49
  • @Herohtar - Easily prevented. Whether this or the other is "how it should be done" is far too context-dependent for us to say from the little information we have. – T.J. Crowder Dec 30 '18 at 09:06
  • Doubtful that what they're trying to accomplish actually requires something so convoluted. – Herohtar Dec 30 '18 at 09:14
  • @Herohtar - It's not convoluted at all, if you think in terms of components rather than megalithic pages. The button click instantiating the component, waiting for it to deliver its result. (In the OP's case, they're just hiding the "component" rather than instantiating it, which isn't ideal, but again, this is extremely fragmentary information to make any kind of informed decision about -- so I just answered what was asked.) – T.J. Crowder Dec 30 '18 at 09:18
-1

The problem is the following: fn() doesn't have return value! fn() only sets an anonymous Event Listener function to input. So use instead:

$('button').one('click', function() {
  const var1="foo",
        var2="bar"
  fn(console.log,var1,var2);
});

function fn(onkeypress,...vars) {
  $('#dgInput').show().focus();
  $('#dgInput').on('keypress',function(e){
    if (e.keyCode == 13) {
      onkeypress($('#dgInput').val(),...vars);
    }
  });
}
#dgInput {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button>CLICK</button>
<br><br>
<input type='text' id='dgInput'>
FZs
  • 11,931
  • 11
  • 28
  • 41