1

So I have a jQuery code which on a button click logs the values of every input field on my page:

I have tried this method with forEach method on inputs but it says it' not a function, why can't I use this method here?

$("#submit").click(e => {
  e.preventDefault();

  let inputs = $("input");

  inputs.each(() => {
    console.log($(this).val());
  });
});

But the problem here is that the this keyword here refers to #submit, How could I achieve my goal here using only the this keyword , and why is this here referring to #submit and not the input? Thanks in advance.

Alex
  • 716
  • 2
  • 15
  • 1
    https://stackoverflow.com/questions/28798330/arrow-functions-and-this and https://stackoverflow.com/questions/31095710/methods-in-es6-objects-using-arrow-functions – j08691 Mar 09 '20 at 16:10

3 Answers3

3

Don't use an arrow function. They don't re-bind this.
Instead, the this of the enclosing lexical scope is used.

$("#submit").click(e => {
  e.preventDefault();

  let inputs = $("input");

  inputs.each(function(){
    console.log($(this).val());
  });
});

Should work just fine.


More information on arrow functions and the behaviour of this:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

NullDev
  • 4,714
  • 4
  • 23
  • 43
  • 1
    Thank you for your response, so In this case the arrow function ignores it's local scope and the this keyword corresponds to the base function? – Alex Mar 09 '20 at 16:21
  • You can still use the arrow function. Receive the reference to the elemnt as an argument instead of using the scope – Rory McCrossan Mar 09 '20 at 16:22
  • @Alex That is correct. – NullDev Mar 09 '20 at 16:24
  • @RoryMcCrossan Of course you could do that. But I don't see a reason for using a lambda expression over a normal function expression here. I mean, not re-binding `this` is pretty much the main use-case of arrow functions. – NullDev Mar 09 '20 at 16:25
  • 1
    @RoryMcCrossan oh ok , would it be possible for you to provide an example, I can't quite visualize what you mean ,thank you. – Alex Mar 09 '20 at 16:25
  • @Alex sure, here you go: https://jsfiddle.net/zne10fp5/1/ – Rory McCrossan Mar 09 '20 at 16:28
0

this is one possible solution;

// should always to assign vars first and then use them
var $this = $(this);
var $submit = $("#submit");
$submit.click(e => {
      e.preventDefault();

      let inputs = $("input");

      inputs.each(function() {
        console.log($(this).val());
      });
    });
Dave Pastor
  • 225
  • 1
  • 6
0

Try this:

function getInputs(){
  let inputs = $("input");

  inputs.forEach(() => {
    console.log($(this).val());
  });
}
$("#submit").click(e => {
  e.preventDefault();
  getInputs()
});

This puts the inputs in a separate function, keeping the this variable from being overwritten.

Helix
  • 116
  • 1
  • 9