1

I’m trying to create a simple loop of animation functions. I've stored their names in an array and am able to log out each object as a string with a click event. However I can't seem to call the corresponding functions of that event

I've tried to do this but I get an error nt[rt] is not a function

arrAnimations[activeScene]()

I've tried many approaches from stack overflow from similar questions, such as creating a helper function like this

myFunction = function(){};   
var arrAnimations = {italy: myFunction};

arrAnimations['activeScene']();//executes the function

and this

var tmp = arrAnimations[activeScene]
window[tmp]

Here is the code:

var arrAnimations = [
  'italy',
  'czech',
  'russia'
]

var activeScene = 0;

document.getElementById('animate').addEventListener("click",
  function incNumber() {
      if (activeScene < arrAnimations.length - 1) {
          activeScene++;
      } else if (activeScene = arrAnimations.length - 1) {
          activeScene = 0;
      }
      // console.log(arrAnimations[activeScene])
  }
)

function italy() { console.log('italy') }

function czech() { console.log('czech') }

function russia() { console.log('russia') }
<div id="animate">Animate</div>

5
  • It looks like it should be window[arrAnimations[activeScene]] Commented Jan 26, 2019 at 15:35
  • 2
    Why don't you create an array of anonymous functions instead of array of function names? Commented Jan 26, 2019 at 15:35
  • 1
    "can't get any to do what I want" is not a precise enough error description for us to help you. What doesn't work? How doesn't it work? What trouble do you have with your code? Do you get an error message? What is the error message? Is the result you are getting not the result you are expecting? What result do you expect and why, what is the result you are getting and how do the two differ? Is the behavior you are observing not the desired behavior? What is the desired behavior and why, what is the observed behavior, and in what way do they differ? Commented Jan 26, 2019 at 15:37
  • Yes, you would need a helper object that stores the functions, next to the array with their names. (Or follow @Mohammad's suggestion) Commented Jan 26, 2019 at 15:37
  • 1
    Btw, the activeScene = arrAnimations.length - 1 assignment should be a activeScene == arrAnimations.length - 1 condition. Or be omitted altogether (just else { … }). Commented Jan 26, 2019 at 15:38

4 Answers 4

1

The array can store the actual functions themselves, instead of the function names.

function italy()  { console.log('italy') }
function czech()  { console.log('czech') }
function russia() { console.log('russia') }

var arrAnimations = [ italy, czech, russia ]

Then locate the item in the array, and call it:

var activeScene = 0;
arrAnimations[activeScene]()

Demo in Stack Snippets

function italy()  { console.log('italy') }
function czech()  { console.log('czech') }
function russia() { console.log('russia') }

var arrAnimations = [ italy, czech, russia ]

var index = 0;

function callNextFunction() {
    index = index >= arrAnimations.length - 1 ? 0 : index + 1
    
    arrAnimations[index]()
}

var btn = document.getElementById('animate')
btn.addEventListener("click", callNextFunction)
<button id="animate">Animate</button>

Sign up to request clarification or add additional context in comments.

Comments

1

In your commented out line:

console.log(arrAnimations[activeScene])

You're trying to call a method on the array, which doesn't exist. It's an array of strings. Instead, you need to get the string value, then use that to call a method on the window.

window[arrAnimations[activeScene]]();

With that said though, I'd make your code a bit simpler and use lambda functions, and avoid a couple of if statements, try this:

<div id="animate">Animate</div>

<script>
    var arrAnimations = [
        () => console.log('italy'),
        () => console.log('czech'),
        () => console.log('russia')
    ]

    var activeScene = 0;

    document.getElementById('animate').addEventListener('click', () => {

        arrAnimations[activeScene]();

        activeScene++;
        activeScene = activeScene % arrAnimations.length;
    });
</script>

Comments

1
italy = () => console.log('italy')
czech = () => console.log('czech')
russia = () => console.log('russia') 

if Array of functions:

let arrAnimationsAsFunctions = [ italy , czech , russia];
arrAnimationsAsFunctions.forEach(animation => animation())

if Array of Strings:

let arrAnimationsAsStrings = [ 'italy' , 'czech' , 'russia' ];
arrAnimationsAsStrings.forEach(animation => eval(animation)())

use eval to run a string as JS code

Comments

0

Is this what you want?

foo = () => console.log('foo')
bar = () => console.log('bar')
baz = () => console.log('baz')

fns = {
  foo,
  bar,
  baz
}

Object.keys(fns).forEach(fn => fns[fn]())

fns['foo']()
fns['bar']()

Note: you can't cast a string to a function like this, at least in Javascript:

let fn = () => {}
let foo = 'fn'
foo()  // X
// foo is a string, not a function, It is just a coincidence that the content of the string is same with the function's name

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.