How to pass optional parameter to a function in react and javascript? - javascript

i want to set an optional parameter to a function using javascript. i have a function defined like below,
const function1 = () => {
setValue(!open);
};
i call it like below in other function
const main_function = () => {
function1();
}
now i want to pass an optional parameter to function1 to accept an optional parameter that sets it to true or false instead of toggling based on previous value.
how can i fix this. could someone help me with this thanks.

I hope this helps someone, you can just set the value to null like code below:
const function1 = ({arg1=null, arg2= false, arg3, ...}) => {
}

Pass a default value like so:
function multiply(a, b = 1) {
return a * b
}
multiply(5, 2) // 10
multiply(5) // 5
Example taken from
MDN docs

You can check the if the argument is defined or not, like:
const function1 = (arg) => {
setValue(arg === undefined ? !open : arg);
};

As far as I can understand you want something like this.
const function1 = (param) => {
setValue(params ? true : false);
}
It will set true if param is available otherwise false.
Correct me if I'm wrong.

we can't make function arguments optional in javascript directly. However, we can assign them a default value, in case no arguments is passed through. this is how you do it-
const abc = (arg1, arg2= 'default value') => {
//arg1 is required. however if arg2 is not passed in any case, the default value //will be used in place.
}

Related

Callbacking a function with arguments

I have an exercise where I have to give three arguments: function and two numbers.
The function which I give has to be activated (each) after x miliseconds for y miliseconds.
I wanted to make helper like this:
function helper(string) {
console.log("Printing string which was given: " + string)
}
but when I do it like this and I try to enable my function ex1_4(helper("some string"), 500,5000) I get an error that Callback must be a function
What am I doing wrong?
function ex1_4(func, x,y) {
const resFunction = setInterval((func), x)
const stop = setTimeout(() => {clearInterval(resFunction)}, y)
}
function helper(string) {
console.log("Printing string which was given: " + string)
}
ex1_4(helper("some string"),500,5000)
helper("some string")
Is a function call which returns a value, in your case it is undefined. If you want to make it into a callback, you need to wrap it in a function like so:
() => helper(“some string”)
In your code:
ex1_4(() => helper("some string"),500,5000)
When you add helper("some string"), you're actually executing the method, instead of sending the method to ex1_4. You should type something like ...
ex1_4(helper,500,5000) // no parenthesis
... just like you did with setInterval((func), x).
However, you want to add parameters to helper, and in this case, you can use bind. You should really learn about bind(), call(), and apply().
ex1_4(helper.bind(null, "some string"),500,5000)
function ex1_4(func, x,y) {
const resFunction = setInterval((func), x)
const stop = setTimeout(() => {clearInterval(resFunction)}, y)
}
function helper(string) {
console.log("Printing string which was given: " + string)
}
ex1_4(helper.bind(null, "some string"),500,5000)

Return a value before executing a function similar to setstate in react

I want to make a function that returns a value that I can check against before executing something if i need to. Similar to reacts setState. So something like:
changeState(initialState => {
console.log(initialState);
return 'Hello';
});
but can also be used simply like:
changeState('hello');
How is this handled? It seems like it should be simple but I for some reason can't get a grasp on how to pull this off. Does anyone know how react handles this situation.
I'm not 100% clear what you are wanting to accomplish but checking the typeof the arguments is probably what you are looking for.
Simple example that assigns an object property value based on function or primitive as first argument
const state = {
foo: 1
}
const changeFoo = (...args) => {
if (typeof args[0] === 'function') {
// assign value as result of function passing in initial value
state.foo = args[0](state.foo)
} else {
// assign value directly
state.foo = args[0]
}
};
// set value directly
changeFoo(2)
console.log('after set 2:', state.foo)// expect 2
// set value as return of function
changeFoo((initial) => initial + 1)
console.log('after func:', state.foo)// expect 3

How do you provide an extra parameter to a function call if the argument is implicitly provided?

export const SelectedChoice: (choiceProps) => { ... }
<ChoicePicker {...props}
onRenderItem={SelectedChoice}
/>
I have this, the argument choiceProps is implicitly provided, but now I want to add a function to the second argument so I can call it inside of SelectedChoice, how do I do this? The issue is that I don't know what is being passed to SelectedChoice so I can't call it explicitly without breaking the function. If I knew what was being passed as choiceProps, I wouldn't have this issue. I feel like it's being called as a callback function and the argument is explicitly provided inside onRenderItem, but I might be mistaken.
You might be able to check the arguments object that implicitly exists in the function body of SelectedChoice as in:
export const SelectedChoice: (choiceProps) => {
if(arguments.length === 1) {
// do something if no function was passed
}
else if(arguments.length === 2 && typeof arguments[1] === "function") {
// call the passed function
arguments[1]();
}
}

Passing along a function to a specific object

It's one of those times where I want to do soemthing, but I'm not sure what it's called...
Hopefully, someone can help!
I have the following function:
function myfunction(object1, object2) { ... }
I want to pass another function onto object1 specifically using the .click method.
I can get this working easily with only one object within the function using the following:
function myFunction(object1) { ... }
$('button').click(function() {
// Passes along another function!
myFunction(anotherFunction());
});
How would someone approach this when there are 2 objects? I can't seem to get anything working. Any ideas? Or am I approaching this the wrong way?
Updated Answer
Assuming still:
function myFunction( function, anotherFunction, ... ) { ... }
If you want to pass specific arguments but be able to omit arguments, you could provide an argument but catch it as falsy:
myFunction( null, someOtherFunction, maybeAnotherFunction )
You then would need to handle the null, perhaps:
function myFunction( function, anotherFunction, ... ) {
let fnc = function;
let fnc2 = anotherFunction;
let ... = ...;
if(fnc) ...
if(fnc2) ...
if(...) ...
...
}
Original Answer
Because you are triggering the function immediately during its passing you might actually want to just send it without initializing it. Try the below and see if this works for you.
function myFunction(object1, object2) {
object1()
object2()
}
$('button').click(function() {
// Passes along another function!
myFunction(anotherFunction1, anotherFunction2);
});
var a = 5,
b = 2;
function check(val1, val2) {
console.log(val1);
console.log(val2);
}
function add() {
return a + b;
}
function mulitply() {
return a * b;
}
check(add, mulitply); // this will send refernce of function's not output
check(add(), mulitply()); // this will converts into like this check(7,10);

Debounce a function with argument

I'm trying to debounce a save function that takes the object to be saved as a parameter for an auto-save that fires on keystroke. The debounce stops the save from happening until the user stops typing, or at least that's the idea. Something like:
var save = _.debounce(function(obj) {
...
}, delay);
Where this falls apart is if I try to save two objects in quick succession. Because the debounce doesn't take the passed in object into account, only the second call to save will fire and only one object will be saved.
save(obj1);
save(obj2);
Will only save obj2, for example.
I could make obj an instance of a class that has its own save method that takes care of debouncing saves to just that object. Or keep a list of partial/curried functions somewhere, but I'm hoping there's a one stop solution out there. Something like:
var save = _.easySolution(function(obj) {
...
}, delay);
What I'm looking for the following string of saves to save each object, but only save each object once.
save(obj1);
save(obj2);
save(obj3);
save(obj2);
save(obj2);
save(obj3);
save(obj2);
save(obj1);
EDIT: Something like this, maybe, just not so convoluted, and something that doesn't mutate the obj with a __save function?
function save(obj) {
if(!obj.__save) {
obj.__save = _.debounce(_.partial(function(obj) {
...
}, obj), delay);
}
obj.__save();
}
You're going to want to create a debounced version of the function for each argument that get's passed. You can do this fairly easily using debounce(), memoize(), and wrap():
function save(obj) {
console.log('saving', obj.name);
}
const saveDebounced = _.wrap(
_.memoize(() => _.debounce(save), _.property('id')),
(getMemoizedFunc, obj) => getMemoizedFunc(obj)(obj)
)
saveDebounced({ id: 1, name: 'Jim' });
saveDebounced({ id: 2, name: 'Jane' });
saveDebounced({ id: 1, name: 'James' });
// → saving James
// → saving Jane
You can see that 'Jim' isn't saved because an object with the same ID is saved right after. The saveDebounced() function is broken down as follows.
The call to _memoize() is caching the debounced function based on some resolver function. In this example, we're simply basing it on the id property. So now we have a way to get the debounced version of save() for any given argument. This is the most important part, because debounce() has all kinds of internal state, and so we need a unique instance of this function for any argument that might get passed to save().
We're using wrap() to invoke the cached function (or creating it then caching it if it's the first call), and pass the function our object. The resulting saveDebounced() function has the exact same signature as save(). The difference is that saveDebounced() will debounce calls based on the argument.
Note: if you want to use this in a more generic way, you can use this helper function:
const debounceByParam = (targetFunc, resolver, ...debounceParams) =>
_.wrap(
_.memoize(
() => _.debounce(targetFunc, ...debounceParams),
resolver
),
(getMemoizedFunc, ...params) =>
getMemoizedFunc(...params)(...params)
)
// And use it like so
function save(obj) {
console.log('saving', obj.name);
}
const saveDebounced = debounceByParam(save, _.property('id'), 100)
Maybe something like:
var previouslySeen = {}
var save = _.debounce(function(obj) {
var key = JSON.stringify(obj);
if (!previouslySeen[key]) {
previouslySeen[key] = 1;
} else {
...
}
}, delay);
You can use internal object in closure for set/get debounced function.
In this example we check if debounced function with this args alredy saved in our memory object while call debounced function. If no - we create it.
const getDebouncedByType = (func, wait, options) => {
const memory = {};
return (...args) => {
// use first argument as a key
// its possible to use all args as a key - e.g JSON.stringify(args) or hash(args)
const [type] = args;
if (typeof memory[searchType] === 'function') {
return memory[searchType](...args);
}
memory[searchType] = debounce(func, wait, { ...options, leading: true }); // leading required for return promise
return memory[searchType](...args);
};
};
Original gist - https://gist.github.com/nzvtrk/1a444cdf6a86a5a6e6d6a34f0db19065

Categories