If I have a function that I want to use in a onClick, such as this
*using ReactJS and Semantic-UI
<Table.HeaderCell
onClick={this.handleSort(items)}
>
where the function returns a reference of a function, such as this
handleSort = (items) => () => {
console.log('now')
}
then, how can I execute this function outside of the onClick event? What doesn't work:
componentDidMount() {
this.handleSort.call(items);
this.handleSort(items);
}
handleSort returns a function, you'll need to invoke it with (), like so:
componentDidMount() {
this.handleSort(items)();
}
I guess you are trying to execute the inner function that logs 'now' to the console.
As a clarification: this.handleSort(items) returns a anonymous function:
() => {
console.log('now')
}
In order to call it, you may do: this.handleSort(items)() to immediately invoke the inner function.
See:
var handleSort = (items) => () => {
console.log('now')
}
// holds the inner function part
var innerFunction = handleSort([]);
console.log(innerFunction.toString());
// Equivalent ways to call it directly
innerFunction();
handleSort([])();
Related
I want to dynamically return different values based on the event that changes the value of var inside the constructor function. When constructor function is created I get the return of the default value which is equal to doA, when I invoke it the first time, I get a call to someFunction from doA. When the event happens, I can see that event variable updates it is reference to refer to doB function, however, when I invoke someFunction a second time, I still get a call to doA instead of doB. Any suggestion of can I achieve what I intent?
Thank you in advance
PS - the code bellow is not a working code, it just a representation of what I am trying to achieve
function doA(){
function someFunction(){};
function someFunctionB(){};
}
function doB(){
function someFunction(){};
function someFunctionB(){};
}
function Main(){
var event;
addEventListener('change', (event) => {
if(someCondition){
event = doA();
}
if(otherCondtion){
event = doB();
}
});
function someOtherFunction(){
}
return{
...event,
someOtherFunction
}
}
const main = new Main();
main.someFunction(); //calling someFunction from doA
//event changes here
main.someFunction() //intent to call someFuntion doB but still calling someFunction from doA
'''
I have a problem where if i want to add a parameter to my click attribute then it calls the function as soon as it renders
here is my test html:
return html`
<button class="menu-btn" #click="${this._OpenSubMenu(1)}>test</button>"
`;
}
And the function:
_OpenSubMenu(test:number) {
console.log("Hello")
}
This output Hello as soon as the page is rendered.
So how can i avoid this while still adding a parameter to my function?
You need to make your function return a function. Your click function will then execute the returned function, and due to closure's will still have access to the params.
eg..
_OpenSubMenu(test:number) {
var that = this;
return function () {
console.log("Hello");
//test is also a closure so you can use here
//that will equal this
}
}
If you want access to this, you could also use an arrow function
_OpenSubMenu(test:number) {
return () => {
console.log("Hello");
//test is also a closure so you can use here
//this will also still be valid here
}
}
So I am calling a function that calls lodash's once function:
if (isPageTwo) {
sendSegmentData(sendEnhancedTrackEvent);
}
And I have the functions defined here:
const pageTwoSegmentEvent = (sendEnhancedTrackEvent) => {
const enhanceableData = {
name: 'Page loaded',
properties: {
...defaultProps,
cid: getCid(),
epid: getEpid(),
name: 'ReviewExperienceModernDoubleStep'
}
};
sendEnhancedTrackEvent(enhanceableData);
}
const sendSegmentData = (sendEnhancedTrackEvent) => {
once(() => {
pageTwoSegmentEvent(sendEnhancedTrackEvent);
});
}
I am trying to pass the sendEnhancedTrackEvent callback function to the pageTwoSegmentEvent function but I guess the way I'm trying to pass it through the once function pageTwoSegmentEvent never gets called. Does anyone know how to do this?
The _.once() method takes a function (func), and returns a function that invokes the wrapped function (func) a single time. According to the docs:
The func is invoked with the this binding and arguments of the created
function.
Which means that whatever arguments you pass to the new function, will be passed to the wrapped func.
In your case:
sendSegmentData has the sendEnhancedTrackEvent param
When sendSegmentData is invoked, it calls once(() => { pageTwoSegmentEvent(sendEnhancedTrackEvent); });, which creates a new function. The new function is not returned or called.
To create sendSegmentData, call once on pageTwoSegmentEvent directly. This will return a new function, that will pass whatever arguments in gets to pageTwoSegmentEvent.
Example:
const { once } = _
const pageTwoSegmentEvent = (sendEnhancedTrackEvent) => console.log(sendEnhancedTrackEvent)
const sendSegmentData = once(pageTwoSegmentEvent)
sendSegmentData('1')
sendSegmentData('2')
sendSegmentData('3')
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
_.once returns the function that you need to invoke. No matter how many times you call this function it will only be invoked once.
Assuming once is an alias to _.once, try changing it to this:
const sendSegmentData = once((sendEnhancedTrackEvent) => {
pageTwoSegmentEvent(sendEnhancedTrackEvent);
});
...
// somewhere else call it
sendSegmentData(theSegmentedData);
This question already has answers here:
The value of "this" within the handler using addEventListener
(10 answers)
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
Original Modal
I want to use a universal app object. To this empty object I will add functions as needed. The issue is that some functions will need to all others within the app object.
So, my question is: how do I construct a large object without having to define all functions inside the object at the time of creation? I would like to split up the chunks of code to not have one astronomical long .js file.
There is a simple example of my original code:
var app = {
tow: function () {
return true;
},
one: function () {
return this.tow();
}
};
// app.one() => returns true
Updated Modal
Here is something I found interesting. I was playing around with the prototype modal and discovered something strange. When I use this model I can add functions that can call other added functions. But, when I create an event listener it is unable to run the code. Can anyone explain why this is?
Modified code with unexpected result:
function modal () {}
modal.prototype.one = function () {
return this.two();
};
modal.prototype.two = function () {
return "cool";
};
modal.prototype.init = function () {
document.getElementById('go')
.addEventListener("click", this.one);
}
var app = new modal();
app.init();
// app.one() => returns true
// event listener => returns "TypeError: this.two is not a function"
JSBIN: https://jsbin.com/vureruziza/edit?js,console,output
this.one called as you done refers to addEventListener function, not to your object. This will solve the issue
modal.prototype.init = function () {
var self = this;
document.getElementById('go')
.addEventListener("click", function(){
self.one()
});
}
bind the click function with this cause the function will need the this context, not the window context. Then call your this.one function in de click handler.
function modal () {}
modal.prototype.one = function () {
return this.two();
};
modal.prototype.two = function () {
return "cool";
};
modal.prototype.init = function () {
document.getElementById('go')
.addEventListener("click", function(e){
console.log(this.one())
}.bind(this));
/*
The following wil also be called but your return value
of your this.one function won't be captured. But your code will run.
.addEventListener("click", this.one.bind(this));
Try replacing it with the above and put a debugger statement in this.one
and see that the code will actualy be ran, just not captured to output.
*/
}
var app = new modal();
app.init();
// app.one() => returns true
// event listener => returns "TypeError: this.two is not a function"
<div id="go">go</div>
Use ES6 fat arrow function. Update modal.prototype.init as below -
modal.prototype.init = function () {
document.getElementById('go')
.addEventListener("click", () => this.one());
}
Edit - If you wanted to debug the issue, you could just console.log the this value in function one like so -
modal.prototype.one = function () {
console.log(this);
return this.two();
};
You will most likely see the window object. You will certainly not see the modal object.
consider this module:
//Adder component
(function init() {
//Initilize variables
const addButton = document.getElementById('add-btn');
const userInput = document.getElementById('user-input');
const userOutput = document.getElementById('user-output');
const App = {
//Register event handlers
registerHandlers() {
addButton.addEventListener('click', function () {
this.addKeyValue.call(App, userInput.value);
});
},
addKeyValue(input) {
userOutput.value = input;
},
};
App.registerHandlers();
})();
When the click event is fired this fails because this.addKeyValue is undefined because at the run time of that function this is referring to the input element and not the App object. But isn't that what the Function.prototype.call function is for? Why is my call function not binding this to App?
But isn't that what the call function is for?
No.
this.addKeyValue.call will get the value of this.addKeyValue, which needs to be a function, then call it. The value of this inside that function call will be what you specify.
It doesn't change the value of this before you call the call function. You can use bind for that.
addButton.addEventListener('click', function () {
this.addKeyValue(userInput.value);
}.bind(App));