Search code examples
javascriptvariablescomparison-operators

Javascript less than that fails when I use a variable for comparison


I have two 'if less then' blocks that don't seem to be working for me when I replace the right hand side of the comparison from Math.PI to my variable, this.bottomChainAngleRads.

Context: I'm animating a chain between two gears, and so iterating over the teeth of two gears to hide/show its links as they rotate

Earlier in the code, the variable is initialized with math, not a string.

this.bottomChainAngleRads = Math.PI + 2 * Math.atan2(...);

Then I want to do something with it every once in a while:

this.step = function() {
  console.log('this.bottomChainAngleRads = ' + this.bottomChainAngleRads  // Just over PI. Usually about 3.4.
              + ' ' + $.isNumeric(this.bottomChainAngleRads));            // Always true.

  // Counting the passing through each if block. Expecting a little in each.
  var frontDisplay = 0, frontHide = 0, rearDisplay = 0, rearHide = 0;

  $(this.frontGear.div).find('.geartooth').each(function(index, el) {
    var totalRadians = measureRotation(el);
    console.log('front totalRadians = ' + totalRadians + ' '    // From 0 to TWO_PI
                + (totalRadians < this.bottomChainAngleRads));  // Always false. WTF.
    if (totalRadians < this.bottomChainAngleRads) { // <================ FAILS. NEVER TRUE.
    // if (totalRadians < Math.PI) { // MOSTLY CORRECT, but expectedly off by minor angle.
      ++frontDisplay;
      // .. do stuff
    } else {
      ++frontHide;
      // .. do other stuff
    }
  });

  $(this.rearGear.div).find('.geartooth').each(function(index, el) {
    var totalRadians = measureRotation(el);
    console.log('rear totalRadians = ' + totalRadians + ' '     // From 0 to TWO_PI
                + (totalRadians < this.bottomChainAngleRads));  // Always false. WTF.
    if (totalRadians < this.bottomChainAngleRads) { // <================ FAILS. NEVER TRUE.
    // if (totalRadians < Math.PI) { // MOSTLY CORRECT, but expectedly off by minor angle.
      ++rearHide;
      // .. do stuff
    } else {
      ++rearDisplay;
      // .. do other stuff
    }
  });

  // Below I expected approximately a 50/50 split on each gear.  Instead, I get...
  console.log('front: ' + frontDisplay + ', ' + frontHide     // Nothing, All.
              + '; rear: ' + rearDisplay + ', ' + rearHide);  // All, Nothing
}

Sorry for the verbose code, but because I feel I've tried so many things, I wanted to give a bigger picture.


Solution

  • The context inside of each callback is not your object instance anymore, this points to individual DOM elements (.geartooth), which obviously don't have property bottomChainAngleRads.

    The simplest fix is to save correct context reference. Try this:

    var self = this;
    $(this.rearGear.div).find('.geartooth').each(function(index, el) {
        var totalRadians = measureRotation(el);
        if (totalRadians < self.bottomChainAngleRads) {
        ... 
    });