Referencing functions within object properties does not work

When I press a key, I have the following:

function action1 () {
    // Do some action.
}

keys = {
    ArrowUp: action1;
}

// Function from P5.js
function keyPressed () {
  console.log( `Key ${key} pressed!` );
  if ( keys[ key ] !== undefined ) {
    // This console.log() shows the referenced function...
    console.log( keys[ key ] );
    // However the function is not getting called.
    keys[ key ](); // It does not work.
  }
}

Why such thing is happening in the P5.js? It works perfect in vanilla JS to avoid lots of IFs.

1 Like

Pasting the sketch below on My Sketch - OpenProcessing action1() is invoked normally: :partying_face:

'use strict';

const keys = {
  ArrowUp: action1
};

function setup() {
  background(100);
}

function action1() {
  console.info('ArrowUp detected!');
}

function keyPressed() {
  print(`Key ${ key } pressed!`);

  const funct = keys[key];

  if (funct) {
    print(funct);
    funct();
  }
}
1 Like

It does not work either. :confused:
I gave up to make it work, no worries.

Your syntax error is one issue, but you should have gotten an err msg on that …

@GoToLoop’s example works just fine, also this fix below of your original works just fine …

const keys = {
  ArrowUp: action1
};

function setup() {
  background(100);
}

function action1() {
  console.log(keys[key]);
}


function keyPressed() {
  if (keys[key] !== undefined) {
    keys[key]();
  }
}
3 Likes

I don’t think action1 is a predefined function…
you have to call it in the function draw()…
just like this

function draw(){
    action1();
}

HOPE IT WORKS…

@kdmb declared the function …

draw() will invoke that function every frame, original post only wants it to be invoked when the ArrowUp key is pressed.

3 Likes

oh, forgot that part :joy:

I don’t want to be rude but, before commenting, read carefully the problem more than once!

1 Like

Well, I got the time to dig in into the problem. The ‘action1’ is in an object, which is lost when I call the function, and the function also calls properties of that object with ‘this.’, that would pointing to that object, but ends transforming the ‘this.’ to the ‘keys’ object, which is not the intention.
If you want to see the code, this is the link project:
https://editor.p5js.org/kdmb/sketches/vU2TNSuRy
The keys object is in ‘scripts/game/character.js’ that have the ‘action1’ which is the jump(), and the keyPressed function is in ‘scripts/scenes/game.js’

really very sorry about that…

The action1 on your 1st post is clearly a function:

How are we supposed to help you if you mislead us and keep replying w/:


A function which is a property of an object and has to deal w/ the JS keyword this is called an instance method:


If I had access to it from the very beginning I coulda given a better advice to you upfront.

Inside the constructor() of your class Character from your file “character.js” you’ve got this block of code commented out:

this.keys = {
  ArrowUp: this.jump,
}

You can use the Function::bind() method in order to clone any function w/ its this permanently bound to a specific object:

You can apply it like this:

this.keys = {
  ArrowUp: this.jump.bind(this)
}

Or like this as well:

this.keys = {
  ArrowUp: Character.prototype.jump.bind(this)
}

From that on, whatever means you use to invoke that cloned method Character::jump() is gonna work, b/c its this can’t be changed anymore!

2 Likes

Sorry about the confusion. I started with the code on the post and I kept changing it to all possibilities but nothing worked for me, maybe I was placing it in the wrong places.

this.keys = {
      ArrowUp: this.jump.bind(this)
}

It worked, finally. Thank you for your help.

1 Like