2

I am trying to retrieve a variable from an if statement nested in a jquery .each function:

var radioAmount;

$('div.amount').each(function() {
  var input = $(this).find('input[type="radio"]');
  if(input.is(':checked')) {
    radioAmount = input.attr('value');
  } else {
    radioAmount = $('#other-amount').val();
  }
});

console.log(radioAmount);

I want radioAmount to return the input value outside of the .each function, but it returns undefined.

I'm sure this should be fairly straight forward and has to do with variable scope but I can't work out what I'm doing wrong.

Or maybe this is the wrong approach completely.

7
  • Your code appears to be working. Does your radio have a value? Does #other-amount exist? Is it a form element of some sort? Does it have a value? Commented Aug 20, 2013 at 10:05
  • If radioAmount is undefined, then there is something else going on that you are not showing us. Possibilities are that radioAmount is not defined in a high enough scope (outside the .each() callback) or that you're doing this inside some async function and expecting radioAmount to get returned from that. Also, why use an .each() loop if you just want one value for radioAmount - that doesn't make sense to me as it can only have one value, but you're iterating over potentially many items and resetting the value over and over. If you only want one value, then pick one of the divs Commented Aug 20, 2013 at 10:11
  • Other possibilities. input doesn't have a value attribute or $('#other-amount') doesn't exist or doesn't have a value. Commented Aug 20, 2013 at 10:13
  • Provide the html mark up ... Commented Aug 20, 2013 at 10:15
  • It is possible that you are not getting into each handler. Check if $('div.amount') returns anything. Commented Aug 20, 2013 at 10:19

3 Answers 3

1

The issue here is not the variable scope but that $('#other-amount') is undefined.

I missed this because I thought it wouldn't matter if a radio input was checked instead.

As suggested in the comments, I have rewritten this without .each():

var radioAmount;
var checkedRadio = $('div.amount').find('input[type="radio"]:checked');
if(checkedRadio.length) {
    radioAmount = checkedRadio.attr('value');
} else {
    radioAmount = $('#other-amount').val();
}
console.log(radioAmount);
Sign up to request clarification or add additional context in comments.

5 Comments

You don't need to use filter. Just var checkedRadio = $('div.amount').find('input[type="radio"]:checked"); or even var checkedRadio = $('div.amount input[type="radio"]:checked");
@RoToRa the first form of your comment would be faster due to the right to left action of the sizzle behind the selection.
@MarkSchultheiss Right. Generally I'd avoid descendant selectors in CSS (and jQuery) due to performance and use child selectors (>) where possible instead.
For jQuery, the find() is better in this case due to performance. In the first example form, it will get the div with amount class, then find within that, in the second example, it finds all the checked radios, then select those within the div.amount - so potentially a full DOM scan in the first phase rather than just within the div.amount.
@RoToRa good point, will update my answer. I was using find() as I thought this would perform better than the general selector in your second version. Unfortunately due to the html I can't use the child selector >
0

I'll move my comments to an answer since guess #5 below seems to have solved it for you:

Without seeing the page and more specifics about the error, I can only guess what things could be causing what you observe. If radioAmount is undefined, then there is something else going on that you are not showing us. Possibilities are:

  1. That radioAmount is not defined in a high enough scope (outside the .each() callback)
  2. You're doing this inside some async function and expecting radioAmount to get returned from that.
  3. Perhaps input doesn't have a value attribute.
  4. Perhaps $('#other-amount') doesn't exist.
  5. Perhaps $('#other-amount') doesn't have a value.

P.S. Why use a .each() loop if you just want one value for radioAmount - that doesn't make sense to me as it can only have one value, but you're iterating over potentially many items and resetting the value over and over. If you only want one value, then pick one of the divs

1 Comment

Thanks @jfriend00 number 5 was indeed the issue. Nothing to do with variable scope.
0
var radioToCheck =$('div.amount').find('input[type="radio"]:checked');
var radioAmount = radioToCheck.length ? radioToCheck.val() : $('#other-amount').val();

Assumption of $('#other-amount') existing and being of an input type with a value.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.