Hello I'm learning about Javascript Callback Function, but I don't know how to set a default value to callback function.
let mul = (num1,num2) =>{
return num1*num2;
}
let cal = (num1,num2,cb) =>{
console.log(`The Answer is ${cb(num1,num2)}`)
}
cal(3,2,mul);
Here the code I tried to set a default value to callback function.
let sum = (num1,num2) =>{
return num1+num2;
}
let mul = (num1 = 3,num2 = 2) =>{
return num1*num2;
}
let cal = (num1,num2,cb) =>{
console.log(`The Answer is ${cb(num1,num2)}`)
}
cal(mul);
Instead of cal(numberone,numbertwo,mul);. Can I only call a function like this cal(mul);.
Edit
let testmul = (num1 = 3,num2 = 2) =>{
let result = num1*num2;
console.log(`${result}`);
}
testmul();
This is what I would like to do. If I doesn't put a number in function. The function will have a default value. But this time I want to try it with a Callback function.
The answers to your question read more: https://nodejs.org/en/knowledge/javascript-conventions/how-to-create-default-parameters-for-functions/
You have to check if the last parameter is undefined and then manually fix all the other parameters before continuing in the code. This case is also valid for modern JavaScript(ES6/ES2015). The example shows you how to do that:
const example = function (param1, optParam, callback) {
if (callback === undefined) {
// only two parameters were passed, so the callback is actually in `optParam`
callback = optParam;
//give `optParam` a default value
optParam = "and a default parameter";
}
callback(param1, optParam);
}
example("This is a necessary parameter", console.log);
example("This is a necessary parameter", "and an optional parameter", console.log);
let DefaultCallback = (args) => {
... do stuff
}
then you can do like this:
function myFunc(param1, param2, callback = DefaultCallback){
return param1;
callback();
}
then if you don't provide a callback like myFunc(2) as you said, it will have the default values of the function defaultCallback and it works for other variables as well, if you want to define default function parameters
Related
onceCopy function (testFunc) {
const copyFunc = (a) => {
const copyFunc2 = (b) => {
return testFunc(a);
};
return copyFunc2;
};
return copyFunc;
};
So the function returns the inner function upon first invocation.
Then returns the inner function of the inner function of the second invocation.
Then the second inner function (third invocation) actually returns the passed argument in the parent function and only invokes it with the character we gave it on the second invocation.
Ideally I want to achieve what I'm achieving over many invocations after only the first one if that makes sense.
Edit: Yes sorry, _.once.
Edit: so first invocation onceCopy SHOULD hold a copy of the Func passed
Second invocation SHOULD trigger the copy and gives an ouput
Third invocation SHOULD give the result of the second invocation so should the fourth, fifth, sixth and so on...
My function does do this, but on the second invocation it stores a function (copyFunc2) again, but I just made that because I need somewhere to store "a".
so like we have
function multiplyBy3 (a) {return a*3}
and then once copy stores a copy of multiplyBy3
const actualFunction = onceCopy(multiplyBy3)
then upon second and third invocation what I want
actualFunction(1) = 3
actualFunction(66) = 3
so the passed function ONLY RUNS ONCE
Cant explain more than this, its in the lodash docs.
I'm not familiar with the function you're trying to reimplement, so feel free to correct me if I misunderstood. To wrap a function and ensure it's only called once you don't need multiple nested wrappings, only one with some state.
You need to keep track of whether you already have a result to return (hasResult) and if so, what that result is (result). Keeping these two variables separate allows you to cover the case when result is undefined while keeping the code easy to read and understand.
function once(wrappedFunction) {
let hasResult = false;
let result;
return (...args) => {
if (hasResult) {
return result;
}
result = wrappedFunction.apply(this, args);
hasResult = true;
return result;
}
}
// An example function to wrap
function multiply(a, b) {
return a * b;
}
const demoFunction = once(multiply)
console.log(demoFunction(1, 2)); // 2
console.log(demoFunction(3, 4)); // 2
console.log(demoFunction(5, 6)); // 2
Is this what you were looking for?
The initial function return is kept on subsequent calls. I used a second variable called in case the first call returns undefined, which should also be returned on subsequent calls.
const once = (onceFn) => {
let called;
let value;
return (...args) => {
if (called) return value;
called = true;
return (value = onceFn(...args));
};
};
function multiplyBy3(a) {
return a * 3;
}
const fn = once(multiplyBy3);
console.log(fn(3)); // 9
console.log(fn(66)); // 9
After calling the function for the 1st time, and getting the result, create a new function that returns the result, and use it whenever the wrapped function is called:
const once = fn => {
let func
return (...args) => {
if(func) return func()
const result = fn(...args)
func = () => result
return result
}
}
const multiply = (a, b) => a * b
const demoFunction = once(multiply)
console.log(demoFunction(1, 2)); // 2
console.log(demoFunction(3, 4)); // 2
console.log(demoFunction(5, 6)); // 2
I have a question regarding curry function..
I know that if I have this simple curry function:
const greeting = (greet) => {
return (name) => {
return `${greet} ${name}`;
};
};
I can call greeting('Hello')('John') and it will return Hello John.
Is there a way to make it flexible say between 1 parameter and 2 parameters, ex: with
the above greeting function, is there a way for me to call greeting('Hello') and greeting('Hello')('John') and it will return Hello and Hello John respectively?
I know that I can do it with greeting('Hello')() and greeting('Hello')('John') but I was just trying to avoid breaking changes because I already have a greeting method and want to extend it using curry function, so I want it to also accept greeting('Hello') without the extra () at the end...
thanks
I can think of only one option that works by coercing the curried function into a string. This won't change the return value but it will allow you to get the result you want depending on context.
const greeting = greet => Object.defineProperties(
name => `${greet} ${name}`, // curried
{
toString: {
value: () => greet,
},
valueOf: {
value: () => greet
}
}
)
console.log(typeof greeting("Hello")) // function, not string
console.log(`${greeting("Hello")}`) // note the string context
console.log(`${greeting("Hello")("World")}`)
If you need the return value to actually toggle between a function and a string however, the answer is no.
In order for greeting("Hello")("John") to return a string, greeting("Hello") must return a function.
There is no way to tell within greeting() how the curried function is going to be called so you cannot detect whether or not to return a function or a string.
Think of it this way, greeting("Hello")("John") is just a short version of...
const fn = greeting("Hello")
// later or maybe never...
fn("John")
You simply don't know how, when or even if that curried function will be called.
Is there a way? Sure. But why? because won't that be "un-currying" it? And you will have to modify the function of-course.
You can always do something like this just get the output your asked for:
const greeting = (greet) => {
const split = greet.split(" ");
if(split.length > 1)
return `${split[0]} ${split[1]}`;
else return (name) => {
return `${greet} ${name}`;
};
};
If you use a helper function for currying, you can get a similar behavior automatically. For example, take the implementation at javascript.info/currying-partials
function curry(func) {
return function curried(...args) {
if (args.length >= func.length) {
return func.apply(this, args);
} else {
return function(...args2) {
return curried.apply(this, args.concat(args2));
}
}
};
}
You can define
const greeting = curry((greet, name) => `${greet} ${name}`)
and call
greeting("Hello", "John")
or
greeting("Hello")("John")
I have this validate function component how I can use It to return callback funcion?
the first file only for check validity
export function checkValidity(value, rules, shouldValidat) {
let isValid = true;
return isValid;
}
the second file caller
import { checkValidity } from "../UI/CheckValidity";
let res = checkValidity(vlaue, validationRules, shouldValidat);
callback = () =>{
alert("call back function is done");
}
how I can call the callback function from the first file using react js?
You need to have a callback in checkValidity function.
So you need to add callback as argument in checkValidity(value, rules, shouldValidat, callback) and then simply do:
export function checkValidity(value, rules, shouldValidat, callback) {
let isValid = true;
/*do your validation here and if it's okay then call callback*/
callback();
return isValid;
}
You should write a function which is like ;
callback(email) {
const re = ..... => it should be validation rule
if(re.test) {
return email;
}
return false;
and when you call function in other function you should give your email or other params for function param .
Two callback examples:
Callback when something is true callback(isValid)
Callback to deal with false (if needed) errorcallback(isValid)
export const checkValidity = (value, rules, shouldValidate, callback, errorcallback) => {
let isValid = true; // hardcoded
isValid ? callback(isValid) : errorcallback(isValid)
return isValid;
}
How to invoke
Pass your functions as arguments 4 & 5, in this case, callback and errorcallback
val denotes a parameter passed back from the callback. in our example above were passing isValid which we are now calling val from where checkValidity() is invoked.
import { checkValidity } from "../UI/CheckValidity";
let res = checkValidity(value, validationRules, shouldValidate);
checkValidity(
value,
rules,
shouldValidate,
(val) => {console.log('callback() if true!! ' + val )},
(val) => {console.log('errorcallback() if false!!' + val}
)
I'm practicing closures and my assigment for now is to :
Write a function once that accepts a callback as input and returns a function.
When the returned function is called the first time, it should call the callback
and return that output. If it is called any additional times, instead of calling
the callback again it will simply return the output value from the first time it
was called.
My callback is:
const addByX = function (num1) {
let number = num1;
function adding(num2) {
console.log(number + num2);
}
return adding;
}
//addByX(2)(8);
let addByTwo = addByX(2);
And my main function is:
const once = function (func) {
let isFirst = true;
let firstOutput;
function inside(numberToPass) {
if (isFirst) {
firstOutput = func(numberToPass);
isFirst = false;
return func(numberToPass);
} else {
return firstOutput;
}
}
return inside;
}
It works, but when I invoke it
const onceFunc = once(addByTwo);
console.log(onceFunc(4)); //should log 6
console.log(onceFunc(10)); //should log 6
it returns my values and also undefined.
And I really can't understand why would it.
Maybe if it works I should not ask this kind of questions, but I'm really curious.
Debugger couldn't clearly answer my question.
I'm suspicious it has something to do with console.log, as abvious as it looks.
Here in JS Bin
The function addByX returns another function, adding. But adding doesn't return anything; it just logs. It's return value is undefined.
I think you intended it to look like this:
const addByX = function (num1) {
let number = num1;
function adding(num2) {
return number + num2;
}
return adding;
}
So the reason that it "worked" is because the callback was printing to the console, rather than where you are invoking it.
I am trying to pass an argument to a function within a function;
function add() {
let x = arguments[0];
function s(num) {
return num + x;
}
}
add(2)(3) //second argument to be passed to 'function s'.
so im wanting the call to return 5.
What is the best approach to this? thanks in advance.
Currying is the name of the construction that allows you to partially apply the arguments of a function. It means that instead of passing multiple arguments to a function and expect a final result, you can pass a subset of this arguments and get back a function that is waiting for the rest of the arugments.
As already pointed by #KevBot, your example is missing the return of the second function and would be:
function add() {
let x = arguments[0];
return function s(num) {
return num + x;
}
}
add(2)(3);
ES6 Curryed Hello World:
curryedHelloWorld = (greeting) => (name) => `${greeting}, ${name}!`;
curryedHelloWorld("Hello")("Tygar");
You can even uncurry the curryedHelloWorld example making it the opposite way:
helloworld = (greeting, name) => curryedHelloWorld(greeting)(name);
helloworld("Hello", "Tygar");