Mattia Surricchio
Mattia Surricchio

Reputation: 1608

Return value of event triggered function

I'm simply implementing a function that is called after a button is clicked. The function works fine, but i'm not capable of making it return a value and assign it to a variable.

I would like to call the function play once the button is clicked, and then return the values (as shown in the code) to a variable, in order to make them accessible for future uses.

I've already implemented all I need (i'm messing around with the web audio api) and it works fine, the test1 variable "embeddeds" the osc and lfo variables and i'm able to access them outside the function.

var ac = new AudioContext();

function play(){
     var osc = ac.createOscillator();
     var lfo = ac.createOscillator();
     osc.frequency.value=1000;
     console.log("Clicked!!");
     returnedObject={};
     returnedObject["value1"] = osc;
     returnedObject["value2"] = lfo;
     return returnedObject;
};

var test1= play();
var test= document.getElementById("mybtn").addEventListener("click", play);

The test1 variable contains what i need, but the test variable doesn't.

How can i assign to a variable the returned object of a function after it's been called by an event?

What i'm getting right now if i use test.value1 is an undefined error, this makes me think that the assignment of the variable failed.

Upvotes: 0

Views: 1019

Answers (3)

zfrisch
zfrisch

Reputation: 8660

Answer:

You can do this, but you have to consider that the value is undefined until the button is clicked.

var ac = new AudioContext();

function play(){
     var osc = ac.createOscillator();
     var lfo = ac.createOscillator();
     console.log("Clicked!!");
     returnedObject={};
     returnedObject["value1"] = osc;
     returnedObject["value2"] = lfo;
     return returnedObject;
};

var test;
document.getElementById("mybtn").addEventListener("click", () => (test = play()));
<button id="mybtn">click me</button>


In order to perform functions with the data you probably want to create a middle function that takes care of whatever work you want done:

var ac = new AudioContext();

function play(){
     var osc = ac.createOscillator();
     var lfo = ac.createOscillator();
     console.log("Clicked!!");
     returnedObject={};
     returnedObject["value1"] = osc;
     returnedObject["value2"] = lfo;
     return returnedObject;
};

function middle(fn) {
return function() {
let data = fn();

//do something
console.dir(data);
}
}

document.getElementById("mybtn").addEventListener("click", middle(play));
<button id="mybtn">click me</button>


Alternatively you can create a Constructor that holds onto the data, thus allowing you to add methods to the Constructor for manipulation at a later time:

function Player() {
  let proto = {};
  proto.ac = new AudioContext();
  proto.data = [];
  proto.play = function() {
    var osc = proto.ac.createOscillator();
    var lfo = proto.ac.createOscillator();
     proto.data.push({
      value1: osc,
      value2: lfo
    });
 proto.latest = proto.data[proto.data.length-1];
        console.log("Clicked!!", proto.latest);
  };
  

  return proto;
}

const myPlayer = new Player();

document.getElementById("mybtn").addEventListener("click", myPlayer.play);
<button id="mybtn">click me</button>

Upvotes: 1

briosheje
briosheje

Reputation: 7446

addEventListener, by design, is meant to don't return anything at all (thanks @AmitJoki for mentioning that) as you can read in the MDN docs.

The relevant part is (excerpt of this section)

Event listeners only take one argument, the Event Object, which is automatically passed to the listener, and the return value is ignored

The reason behind that is that addEventListener is just meant to register an event, not to handle the result of it.

If you want to assign the result to the global variable test, you should just do that inside your play callback.

Upvotes: 0

Swapnil Shukla
Swapnil Shukla

Reputation: 229

I will suggest you to use closure instead. Try something like this.

 // closure
        function audioControl() {

            var ac = new AudioContext();
            var props = {
                value1: ac.createOscillator(),
                value2: ac.createOscillator()
            };
            // function play
            function play() {
                osc.frequency.value = 1000;
                console.log("Clicked!!");
                props.value1 = "_modified_value";
                props.value2 = "_modified_value";
            }
            return {
                props: props,
                play: play
            }
        };

        var test1 = audioControl();
        var test = document.getElementById("mybtn").addEventListener("click", test1.play);

        // now you can get values anywhere anytime using
        // -- test1.props.value1;

Upvotes: 0

Related Questions