2
\$\begingroup\$

Just looking for a way to include a single validation function inside of another function, that will stop any other lines from executing if it fails.

NOT an if statement... I'm trying to avoid nesting, because.. idk, I want to try to avoid it as much as possible.

So.... Is it bad to throw an Error to do this? I can't use return because it only ends the checkAnimationState(); but it doesn't also break out of the moveBlock() function...

JS FIDDLE

$(function(){
    // cache dom 
    var $button = $('#button');
    var $block = $('#block');

    // event handlers 
    $button.on('click', moveBlock);

    // functions
    function checkAnimationState(){
      if(!$block.hasClass('animating')){
        $block.addClass('animating');
      } else {
        throw Error('Block is already animating... BE PATIENT.');
      }
    }

  function moveBlock(){
    checkAnimationState(); // prevent animation if already animating.. validation.. 
    $block.animate(
        {marginLeft:'400px'},
      {
        duration: 3000,
        easing: "linear",
        complete: function(){
            $block.removeAttr('style').removeClass('animating');
        }
      }
    ); // end .animate();
  }
});
\$\endgroup\$
1
  • \$\begingroup\$ !isAnimationRunning() && $block.animate(... No if. \$\endgroup\$ Commented Dec 1, 2016 at 5:13

1 Answer 1

1
\$\begingroup\$

You have some possibilities:

1. If you wanna throw and error it's advised to use try...catch to handle the error, also this way the action the user's done will be executed when the condition is matched (when the block is finished animating) if you use finally. try...catch...finally DEMO

$(function(){
  // cache dom 
    var $button = $('#button');
  var $block = $('#block');

  // event handlers 
    $button.on('click', moveBlock);

  // functions
    function checkAnimationState(){
    if(!$block.hasClass('animating')){
        $block.addClass('animating');
    } else {
        throw Error('Block is already animating... BE PATIENT.');
    }
  }

  function moveBlock(){
    try{
        checkAnimationState(); // check for animation - essentially validation
    }
    catch(e){
        console.log(e);
        return false;
    }
    finally{
      $block.animate(
        {marginLeft:'400px'},
        {
          duration: 3000,
          easing: "linear",
          complete: function(){
            $block.removeAttr('style').removeClass('animating');
          }
        }
      )
    }
  }
});

2. You can use callback inside your checkAnimationState() function to execute or pass the animation command: callback DEMO

$(function(){
  // cache dom 
    var $button = $('#button');
  var $block = $('#block');

  // event handlers 
    $button.on('click', moveBlock);

  // functions
    function checkAnimationState(callback){
    if(!$block.hasClass('animating')){
        $block.addClass('animating');
      callback();
    }
  }

  function moveBlock(){
    checkAnimationState(function(){
      $block.animate(
        {marginLeft:'400px'},
        {
          duration: 3000,
          easing: "linear",
          complete: function(){
            $block.removeAttr('style').removeClass('animating');
          }
        }
      )
    }); // check for animation - essentially validation
  }
});

3. You can have your checkAnimationState() function return a value wether the condition is matched or not and use an if(...) statement. (I know this one is probably not what the OP wants, but I just wanted to mention it for other people who may stumble upon this question) if (...) DEMO

$(function(){
  // cache dom 
    var $button = $('#button');
  var $block = $('#block');

  // event handlers 
    $button.on('click', moveBlock);

  // functions
    function checkAnimationState(){
      var isAnimating = !$block.hasClass('animating');
    $block.addClass('animating'); //since jQuery wont add an existing class, no need to check for it's existance before adding
    return isAnimating;
  }

  function moveBlock(){
    if(checkAnimationState()){ // check for animation - essentially validation
      $block.animate(
        {marginLeft:'400px'},
        {
          duration: 3000,
          easing: "linear",
          complete: function(){
            $block.removeAttr('style').removeClass('animating');
          }
        }
      )
    }
  }
});
\$\endgroup\$
2
  • \$\begingroup\$ Well done! I have used option 3 before, but I think option 2 look the cleanest and I might pursue that one. Option 1 is kind of like what I am doing, but the proper way to do (the way you did it), looks so chunky, i don't like it. Thanks for the advice! \$\endgroup\$ Commented Dec 2, 2016 at 1:12
  • \$\begingroup\$ you're welcome, just remember in different situations different approaches may be required! BTW my favorite is option 2 too :) \$\endgroup\$ Commented Dec 2, 2016 at 10:12

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.