I need to execute 2 functions based on one onClick event. for this, I found some methods Via stackoverflow. (Referred Call multiple functions onClick ReactJS)
But, in my case if I specified as onClick={this.handleClick} works as expected. But if I specified as onClick={(event) => {this.handleClick()}}, when clicking on button nothing happens. What could be the reason for this?
What is the optimal way of calling two functions one by one on one onClick where second function call depends on the result of first function call.
You can try the following
Your onClick goes like this which by default sends an event
onClick={this.handleClick}
handleClick event
handleClick = (event) => {
fetch.fetchUrl(url [, options], ()=> {
this.getFoo();
})
}
getFoo = ()=>{}
Second way
You can send event by binding the function
onClick={this.handleClick.bind(this, additionalParameter)}
now click function would look like
handleClick = (additionParameter, event) =>{}
Additionally, If you would like to send additional parameters alongside you can go with the second way. Both the ways would still pass events attached with your handler.
In Javascript, this is not defined statically for a piece of code (like in 99% other languages), but rather taken from the calling context (i.e. it is dynamically scoped), so it can differ depending on who calls the function and when.
In the second case, this evaluates late: when the function is called. In the first case, it is evaluated when the event is attached (so it is "correct").
The solution is simply to use the first version - there is nothing you gain by calling it late (the event will be passed anyway, as the first argument).
Calling first function inside second should work. PFB the steps -
Define first function.
In second function definition, fist call first function and use the first function output accordingly for further operation statement in second function's definition.
call second function on click event.
This will lead to call second function but will do operation on the basis of the output provided on calling first function.
Related
I have looked over a bit of textbooks and blog posts but most seem just mumble through without a clear explanation...
in a event handler in React, I was told to write,
onChange = {() => setValue(someValue)}
onChange = {() => this.props.someFunction(someValue)}
I just don't understand why I cannot simply write something like
onChange = {setValue(someValue)}
onChange = {this.props.someFunction(someValue)}
since in my understanding setValue is a function by itself already, "() =>" look absolutely redundant to me.
On the other hand, if the event is defined within a class then I am allowed to write like this
onChange = {this.someFunction}
How come I am not required to write as aarow function in this case then? Like
onChange = {() => this.someFunction}
Isn't that double standard???
Because this:
this.someFunction
and this:
this.someFunction()
are two very different things. The first one is a reference to the function itself, whereas the second one executes the function and evaluates to its return value.
So when you do this:
onChange = {this.someFunction}
you're telling it:
When the value changes, execute this.someFunction and pass it the change event.
But when you do this:
onChange = {this.someFunction()}
you're telling it:
Execute this.someFunction right now, passing it nothing. When the value changes, execute whatever this.someFunction returned (which probably isn't an executable function) and pass it the change event.
The purpose of the arrow function is to create a function where one doesn't already exist. So if you just have a simple function reference, pass it:
onChange = {this.someFunction}
But suppose you want to do two things, not just call that one function. In that case you'd wrap those two things in an anonymous function:
onChange = {(e) => {
this.someFunction(e);
somethingElse();
}}
Or even simpler, suppose you have a simple function reference but it exepcts the new changed value instead of the change event itself:
onChange = {(e) => this.someFunction(e.target.event)}
Basically you create a function if you don't already have one which does what you want.
If I have multiple functions passed to a click event i.e.
#click="
inputHandler();
sendToken(computedUser.email);
responseMessage();
"
The function with an event parameter:
inputHandler(e) {
// code
}
Won't run. If I pass it on it's own:
#click="inputHandler"
It works fine.
Why is this and how can I get around it?
Internally Vue uses some RegExps to decide what form of event handler you're using.
If it seems to be the name of a method it will call it and pass the event.
If it seems to be inline code it'll just run it. In this case the event object is accessible as $event.
So:
#click="inputHandler($event)"
is roughly equivalent to:
#click="inputHandler"
Strictly speaking these aren't quite the equivalent, for example with component events that emit multiple arguments you'll only get the first one using $event like this.
See https://v2.vuejs.org/v2/guide/events.html#Methods-in-Inline-Handlers
For a deeper understanding see the Vue source code:
https://github.com/vuejs/vue/blob/0baa129d4cad44cf1847b0eaf07e95d4c71ab494/src/compiler/codegen/events.js#L96
Give your eyes a few minutes to adjust and it isn't too difficult to understand.
Personally I try to avoid anything more complicated than a single method call in the inline listener. Instead I'd suggest having something like #click="onSendClick" and let the method onSendClick worry about the details.
If I recall correctly, vue creates a wrapper function, if the passed value isn't a function. So
inputHandler();
sendToken(computedUser.email);
responseMessage();
actually get's turned into
function wrapper(){
inputHandler();
sendToken(computedUser.email);
responseMessage();
}
And as you can see the arguments passed to wrapper are lost.
The easiest way to fix this is probably to create a new method that accepts the event parameter and calls all of your function and use that one in the event handler.
Here's a function where it suppose to work when I click a "button
but surprisingly it immediately invoked without calling!
const show_card = (shopping_card_checkout) => {
console.log("ali el-deeb");
};
document.querySelector('.fa-shopping-cart').addEventListener('click', show_card()) ;
If I tried to redo the code after the event listener it says reference error as I called the function before declaration.
Help a beginner.
Saw your post request in JS FB group and thought I'd answer here.
First you need to use document.ready or make sure that all js is loaded as last cause else the element might not yet exist. This is not th cause of your problem btw. The problem I explain as last but some advice. You use a class and querySelector, querySelector will fetch the first element in the document and if you want all elements returned you need querySelectorAll and this is not unique or would you like to bind the same action and functionality to many elements? So better would be to use the unique id of an element and use something like:
const myElement = document.getElementById("idName");
myElement.addEventListener("click", myFynction);
const myFunction = () => console.log("Clicked");
The real cause of your issue
You bind the function to the click event and bind it with () behind it and that triggers the execution cause now you don't bind the function but the result of the bound function, you can't pass parameters like that to a bound event. You will need to fetch them inside the function cause only event and a callback can be triggered.
So your working code is:
const show_card = (shopping_card_checkout) => console.log("ali el-deeb");
document.querySelector('.fa-shopping-cart').addEventListener('click', show_card);
And if only one return or one statement inside an arrow function there is no need for the curly brackets and no need to use return since it will automatically return the result of the oneliner.
Hi so I am just wanting to understand how javascript/react is handeling whats going on when I have a function triggered from an event . Im going to show three different code segements, 2 of which work, one of which didnt, and see if I am understanding them correctly. :)
setField(e){console.log("in setfield", e)}
<select multiple className="form-control" id="sel2" name="sellist2"
onChange={() => this.setField()}>
this doesnt work because it is passing a null value to a function that expects a value, in this case e. however, if the function was just submitting something already in state, that would be reasonable way to do it.
setField(e){console.log("in setfield", e)}
<select multiple className="form-control" id="sel2" name="sellist2"
onChange={(e) => this.setField(e)}>
this works because it is getting the event as e and then passes it to the function. How does it know to associate the event to e? does this functionality extent to other things when dealing with html?
setField(e){console.log("in setfield", e)}
<select multiple className="form-control" id="sel2" name="sellist2"
onChange={this.setField}>
This one I really dont understand why it works, but it does. I am assuming that it inherently know to pass the event as default to the function. again does this inbuilt logic occur anywhere else, maybe not neccessarily for events?
Thanks again. Im new to javascript so it is interesting to learn all the idosyncracies of javascript. sadly most of then learning is through frustration of debugging!
All functions in javascript can be passed an arbitrarily large number of parameters, even if the function doesn't do anything with them. For example, the following is legal, if useless:
function thingThatExpectsZeroParams() {
console.log('hello');
}
thingThatExpectsZeroParams(1, 2, 3, 4, [5], 'six');
Six pieces of data were passed into the function, but nothing happened with them because the function didn't do anything with them. To get access to the values passed in, you just need to pick a name that you're going to call it. This name is local to your function and can be anything you want.
function callback(event) {
console.log(event);
}
// I could also just have easily called it something else, and the code would work just as well
// function callback(quesoBurrito) {
// console.log(quesoBurrito);
// }
callback('hello');
So when you set up a listener like this:
onChange={() => this.setField()}
Your function will be called, passing in the event object. But since your function doesn't give the first parameter a name, you have no way to access it, and then when you call this.setField, you pass nothing in there either.
In contrast, with this listener:
onChange={(e) => this.setField(e)}
Your function will again be called, passing in the event object. This time, you named that argument 'e', and can then do with it what you will, in this case forwarding it along to setField.
And when you do this:
onChange={this.setField}
You cut out the middleman. this.setField will get called directly, passing in the event object. Presumably, setField is expecting this, and does something with the object it was passed.
It's not complicated. Whatever Javascript function you assign to onChange will get called at the appropriate time and passed one single argument generally known as e. You can give that argument any name you want in your function (or not declare it at all), but the first argument will be there.
So, when you do this:
onChange={() => this.setField()}
You are ignoring the argument passed to your event handler and then inside that event handler you're calling this.setField() which to no surprise does not pass any argument to setField(). In reality, what's actually happening is this:
onChange={(e) => this.setField()}
How does it know to associate the event to e? does this functionality extent to other things when dealing with html?
The DOM specification says that when an onChange event handler is called, it will be passed the e object as the first argument (whether you declare it or not, it's there as the first argument to the function). This is just how callbacks work in Javascript. The caller of the callback decides what arguments they are going to pass the callback. It's up to you when you declare your callback whether you declare the argument and use it or not. Regardless of how you declare it, the caller passes it.
For this section of code:
onChange={this.setField}
You are say that the function you want to be the onChange event handler is your setField() method. So, no surprise, when the DOM calls that method, it will pass the event object as the first argument just like in the above example.
This one I really dont understand why it works, but it does. I am assuming that it inherently know to pass the event as default to the function. again does this inbuilt logic occur anywhere else, maybe not neccessarily for events?
As described earlier the DOM specification is where this event handler is specified. In the definition of that, it describes what arguments will or won't be passed to whatever callback function you register as this event handler. This is true of all callbacks in Javascript. The caller decides what it will pass to the callback. This is not specific to this type of event handler. Callbacks are used lots of places in Javascript. Even something like array.filter() takes a callback and it's the caller of the callback (the implementation of the Array object in that case) that determines what arguments are passed to the callback.
I am a beginner in javascript. and have no experience in programming, at all.
So I'd like you to be generous to beginner.
And here is my question.
I'm trying to code javascript unobtrusively.
So I put in all of my js codes into external js file. for example : test.js
and deleted these codes. to do unobtrusive js coding. for example :
and I tried to use these 2 methods :
variable.onclick=test(arg1, arg2);
variable.addEventListener('click',test(arg1, arg2),true);
but these triggers didn't work.
to put it delicately, function test(arg1, arg2) worked right after dom loding finished. regardless of activating 'click' trigger.
So I spent several hours solving this problem, and finally got a solution. this is it.
variable.onclick = function(){
variable.addEventListener('click',test('arg1','arg2'),true);
}
I wanna know why first two methods didn't work, and why that solution works well.
I solved the problem, but don't know why, and how...
In JavaScript, when you reference a function by name and follow that reference by a parenthesized list of arguments, that means that you want to call the function, right then and there. Thus a statement like
variable.onclick=test(arg1, arg2);
will assign to the "onclick" property the value obtained by calling the "test" function. In other words that statement means
Please call the function "test" passing it "arg1" and "arg2", and assign whatever it returns to the "onclick" property of the object referenced by "variable".
An event handler must be a function, however, and your "test" handler probably returns either nothing, or something that's not a function. So it didn't work.
Your solution, however, is also incorrect. You're successfully assigning a function to the handler property, but your function is itself installing another event handler. There's no reason to do that here, and in general setting up event handlers from within other event handlers is a suspicious practice. All you need is:
variable.onclick = function() { test(arg1, arg2); };
variable.onclick requires a function declaration by design. In your case you could have just done
variable.onclick = function(){
test(arg1,arg2);
};
The way you did it won't work because you're not giving the click handler any instructions. The corrections I have made say that when the variable (the one with the click handler attached) is clicked trigger this function that will in turn trigger the test function.
Same thing goes for the second one
variable.addEventListener('click', function(){
test(arg1,arg2);
});
This works again because you are saying when this variable is clicked run the function that will trigger the test function.
Basically you are trying to assign the result of running a function, the test function as a task for the click handler to run. This won't work except maybe your test function returns a function that contains code that you want to run when the click event is triggered. Hope this helps.