-1

I have done some javascript coding in my views controller.

The first time I visit the route it works as it's suppose to, but when I go to another route and go back to it, the javascript seems to be executing twice and the effect that I've done is messed up (doubled).

Here's the code that I have:

'use strict'

angular.module('myApp')
.controller('FuncionesCtrl', function($scope) {
  $scope.viewName = 'Funciones';

  var count = 0;
  var array = [
    'identificada',
    'en espera',
    'entre tres'
  ];

  $('#teasers').html(array[0]);

  setInterval(function (){
    if(count == 2) {
        console.log('if');
        count = 0;
        $('#teasers').slideUp(500);
        setTimeout(function (){
            $('#teasers').html(array[count]);
        },500);
        $('#teasers').slideDown(500);
    } else {
        console.log('else');
        count ++;
        $('#teasers').slideUp(500);
        setTimeout(function (){
            $('#teasers').html(array[count]);
        },500);
        $('#teasers').slideDown(500);
    }
  }, 2000);
});

This is an animation where a string slides up (disappears) and then slides down as a different word. The first time it works nice, but after I visit the route again, the animation seems to speed up.

How can I fix this?

Thanks!

edit

I have done some changes:

'use strict'

angular.module('myApp')
.controller('FuncionesCtrl', function($scope, $interval) {
  $scope.viewName = 'Funciones';

  clearInterval(interval);

  var count = 0;
  var array = [
    'identificada',
    'en espera',
    'entre tres'
  ];

  $('#teasers').html(array[0]);

  var interval = setInterval(function (){
    if(count == 2) {
      console.log('if');
      count = 0;
      $('#teasers').slideUp(500);
      setTimeout(function (){
        $('#teasers').html(array[count]);
      },500);
      $('#teasers').slideDown(500);
    } else {
      console.log('else');
      count ++;
      $('#teasers').slideUp(500);
      setTimeout(function (){
        $('#teasers').html(array[count]);
      },500);
      $('#teasers').slideDown(500);
    }
  }, 2000);
});

the clearInterval doesn't seem to do anything.

solution

I've manage to figure it out:

'use strict'

angular.module('myApp')
.controller('FuncionesCtrl', function($scope, $interval) {
  $scope.viewName = 'Funciones';

  // clearInterval(interval);

  var count = 0;
  var array = [
    'identificada',
    'en espera',
    'entre tres'
  ];

  $('#teasers').html(array[0]);

  var interval = $interval(function (){
    if(count == 2) {
      console.log('if');
      count = 0;
      $('#teasers').slideUp(500);
      setTimeout(function (){
        $('#teasers').html(array[count]);
      },500);
      $('#teasers').slideDown(500);
    } else {
      console.log('else');
      count ++;
      $('#teasers').slideUp(500);
      setTimeout(function (){
        $('#teasers').html(array[count]);
      },500);
      $('#teasers').slideDown(500);
    }
  }, 2000);

  $scope.$on('$destroy', function (e){
    $interval.cancel(interval);
  });

});

This:

$scope.$on('$destroy', function (e){
  $interval.cancel(interval);
});

does the trick.

Reference: https://stackoverflow.com/a/14238039/3632722

Community
  • 1
  • 1
Johhan Santana
  • 2,336
  • 5
  • 33
  • 61

2 Answers2

0

Your problem is that you set one timer using setInterval and you don't destroy it at all. That's why when you set second timer it will be 2 timers executed asynchronously

You should reset timer after using it:

var myTimer = setInterval(myFn, 4000);

clearInterval(myTimer);
suvroc
  • 3,058
  • 1
  • 15
  • 29
0

First of all all the DOM operations should be moved to directives according to documentation

Do not use controllers to:

Manipulate DOM — Controllers should contain only business logic.

Then, you should use $destroy event to remove timer. Here is plunker.

Denis
  • 747
  • 4
  • 13
  • ah, I see, I haven't done much with directives as I don't really understand how they work so well. I'll have to read more about it, but I figured an easier, faster way to do it for now would be with regular jquery/javascript in the controller. I've edited the question with the current(for now) solution. – Johhan Santana Jan 05 '16 at 13:29