I was wondering if anyone could clarify the following.
What is the difference between this:
function(arg).then((ret) => {
anotherFunc(ret);
}).catch(error)
and this:
function(arg).then((ret => {
anotherFunc(ret);
})).catch(error)
Difference is the brackets when the promise is returned.
Your second example looks strange. I think your question has to do more with arrow functions syntax. If arrow functions have one argument, you can skip the parentheses. For example .
const logA = a => console.log(a);
const logB = (b) => console.log(b);
As you see, logA argument doesn't have (), logB argument does have (b). They both work exactly the same way, just a syntax preference.
function(arg).then((ret) => {
anotherFunc(ret);
}).catch(error)
OR
function(arg).then(ret => {
anotherFunc(ret);
}).catch(error)
Are the same.
Related
// ....react component
const [fruitDetail, setFruitDetail] = useState(null);
useEffect(() => {
if (!fruitName) {
return;
}
// Method 1
getFruit(fruitName).then((data) => {
console.log(data);
setFruitDetail(data);
});
// Method 2
getFruit(fruitName).then(setFruitDetail);
}, [fruitName]);
return fruitDetail;
I'm very curious about that why Method 1 and Method 2 are equivalent. Is it a Syntactic sugar ?
You can look at method 1 as an explicit way of calling the function. The .then method gets passed the result of getFruit(fruitName)..which you could name whatever you wanted, in your case you chose to call it data. Then you used that variable, data to make two function calls. So you explicitly refer the response by the variable name data.
In your method 2, the variable is implicit. Meaning, because of the way .then works, Javascript knows .then expects one argument, which is the result of the getFruit(fruitName). The .then method takes the result and passes it as the first argument to setFruitDetail...it would also be the same thing to say getFruit(fruitName).then(response => setFruitDetail(response)).You just don't need to specifically put the response variable since it is the only thing being passed and only thing being used.
then function calls any passed function/callback with the promise result.
setFruitDetail is just a function so is ()=>{} albeit anonymous one. You can also pass console.log and see what it does like this getFruit(fruitName).then(console.log). I would suggest to have a look at basic promise implementation.
Is it a Syntactic sugar ?
No, it is not. Because, it's just the another way to pass callback function.
There is example to make clear:
let api = async () => {
return new Promise((solve, reject) => {
setTimeout(() => solve('result'), 1000);
})
};
//your setFruit is a callback. Let example:
let setFruitDetail = (fruit) => console.log(fruit);
//there is no different when you pass a call back into then function.
api().then(setFruitDetail);
api().then(fruit => setFruitDetail(fruit));
//you can imagine that in then function will get param you input into to call a callback.
let otherApi = (callback) => {
let result = "result";
callback("result");
}
otherApi(setFruitDetail);
otherApi(fruit => setFruitDetail(fruit));
I'm looking into the use cases for the good old void operator. One that I've seen mentioned is for preventing arrow functions from "leaking" their result, because of the way they're often written (see fn0 in example below).
So the argument is to use void to prevent such leaks in the cases you don't actually need the result (see fn2) but I don't really see what the difference is with just wrapping the statement in brackets (see fn1).
function doSomething(number) { return number + 1 }
const fn0 = () => doSomething(1)
const fn1 = () => { doSomething(1) }
const fn2 = () => void doSomething(1)
console.log(fn0()) // 2
console.log(fn1()) // undefined
console.log(fn2()) // undefined
Could someone explain to me what the differences are between fn1 and fn2? Does it do something different "under the hood"? Is it just a matter of convention / readability?
All that void does is:
The void operator evaluates the given expression and then returns undefined.
So, it's the same as returning undefined.
When you don't explicitly return anything from a function, undefined is returned by default. So there's no difference here.
Other equivalents:
function doSomething(number) { return number + 1 }
const fn1 = () => { doSomething(1) }
const fn2 = () => void doSomething(1)
const fn3 = () => {
doSomething(1);
return undefined;
}
function fn4() {
doSomething(1);
}
function fn5() {
return void doSomething(1);
}
function fn6() {
doSomething(1);
return void 'foo';
}
console.log(fn1()) // undefined
console.log(fn2()) // undefined
console.log(fn3()) // undefined
console.log(fn4()) // undefined
console.log(fn5()) // undefined
console.log(fn6()) // undefined
(note that the use of an arrow function vs a non-arrow function doesn't make a difference, except for the fact that arrow functions can lack {s, in which case they implicitly return the following expression, which may be undefined or not)
...but I don't really see what the difference is with just wrapping the statement in brackets...
There isn't any significant difference, both achieve the same result. Using void is just more characters and more obscure. :-)
Could someone explain to me what the differences are between fn1 and fn2? Does it do something different "under the hood"?
Not really. It takes a different path to the same destination, but in both cases the result of calling the functions is undefined. As you know, fn1 gets there by using a full function body (the {}), and fn2 gets there by applying the void operator, but there's no subtle difference lurking in there.
Maybe you need to change the view on void, because this can clearly show in the code, to throw away a return value from a function by using a call and omit the result of it.
For example, if you have
void someFunction();
you describe a pattern, which returns something and this result is not used in the code.
If you have just this
someFunction();
and the function returns something useful, the review of the code may mention the unused result of it.
This question already has answers here:
How to return anonymous object from one liner arrow function in javascript? [duplicate]
(3 answers)
Closed 3 years ago.
I am having code from youtube tutorial, and i can not figure out why do we need parentheses(commented line), and if anyone can explain in simple way this code... thanks
const [{count, count2}, setCount] = useState({count: 10, count2: 20})
return (
<div className="App">
<button onClick={ () =>
setCount(
currentState => (//can not understand
{...currentState, count: currentState.count+1}
)
)}>+</button>
<h5>Count 1: {count}</h5>
<h5>Count2: {count2}</h5>
</div>
)
This has nothing to do with the spread operator.
The => of an arrow function can be followed by either:
An expression
A block
Since, in JavaScript, a { can start a block or an object initializer (which depends on context), anywhere you could put a block but want an object initializer you need to add wrap it in () so that the { is treated as the start of an expression.
why do we need parentheses
I guess because without them (), it won't work, throws the error even on compile time.
setCount(
currentState => (//can not understand
{...currentState, count: currentState.count+1}
)
)
setCount is a setState hooks. It has 2 syntax:
setCount( newStateOfCount ) (set state with direct value)
setCount( oldCount => newCount ) (set state using a callback)
And yours is the second one. With the callback return an object, you have 2 options:
currentState => {
return {
...currentState,
count: currentState.count+1
}
}
which is more verbose than
currentState => ({
...currentState,
count: currentState.count+1
})
So in the tutorial he used the second syntax, because it's more concise.
Without the parentheses it doesn't work:
currentState => {
...currentState,
count: currentState.count+1
}
Because the parser will understand that { is the begin of a function body, rather than an object, it won't be able to figure it out, without you explicitly give it the ()
I am studying JavaScript syntax. I occasionally see a pattern that confuses me: an equals sign on the right hand side of the arrow. For example, something like this:
.then(data => myVariable = data)
I don't know what is going on in that syntax. It looks like it is taking the value of data and assigning it to the variable named myVariable. Can somebody explain this?
You're right. It's an arrow function (without an accompanying block) that "returns" an assignment expression - in effect doing an assignment of data's value to myVariable and returning the right hand side, though that might not be utilized in this case.
In a more simplified case:
let foo = 3;
function foobar(callback) {
const result = callback(5); //call callback with 5 as argument
console.log(result); //5
}
foobar(five => foo = five); //assigns 5 to foo
console.log(foo); //5
This is generally not the most readable option and your question proves this. I would recommend adding a block like so (if you don't intend on actually returning the right hand side value):
myPromise.then(data => {
myVariable = data;
});
In which case there is no implicit return of the assignment expression's right hand side and makes the intent clearer. Also, assignments such as what you're doing right with what I assume to an asynchronous promise are not encouraged.
Maybe look into async/await or other new ES features to deal with asynchronous code other than using variable assignments which may run into some problems if not used correctly.
This is called fat arrow function in ES 6 . It is used for many purposes like
1.Arguments
If we want to pass and argument to a function.
Old Syntax :
let sum = function(x,y){
return x+y;
}
New Syntax with fat arrow
let sum = (x,y) => x+y;
//ES5
var setNameIdsEs5 = function setNameIds(id, name) {
return {
id: id,
name: name
};
};
// ES6
var setNameIdsEs6 = (id, name) => ({ id: id, name: name });
console.log(setNameIdsEs6 (4, "Kyle")); // Object {id: 4, name: "Kyle"}
Note : Return statement is not required in fat arrow of it is only one line .
2. Anonymous Function.
// ES5
API.prototype.get = function(resource) {
var self = this;
return new Promise(function(resolve, reject) {
http.get(self.uri + resource, function(data) {
resolve(data);
});
});
};
Using an arrow function, the same result can be achieved more concisely and clearly:
// ES6
API.prototype.get = function(resource) {
return new Promise((resolve, reject) => {
http.get(this.uri + resource, function(data) {
resolve(data);
});
});
};
I want to better understand es6 arrow functions.
Given the following example:
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
// snip actual enhancer logic
return {
...store,
dispatch
}
}
}
Describing the above in words:
Our exported function (applyMiddleware) takes an array parameter with spread.
Then applyMiddleware returns a nameless function with a createStore parameter, which returns another nameless function this time with three parameters.
So without the arrows it would look like this:
export default function applyMiddleware(...middlewares) {
return function(createStore){
return function(reducer,preloadedState,enhancer){
//some logic
return{...store,dispatch}
}
}
}
My questions:
Am I correct?
What is the common use case/code paradigm we see here?
The answer to your first question is more or less (see my comment). The answer to your second question is that the pattern you are seeing is a combination of using a closure and currying. The original parameters to the exported function get gathered into an array called 'middlewares' that the returned functions close over (i.e. have access to). The function then can be called again with yet another parameter 'createStore' then another function is returned that can accept even more parameters. This allows one to partially apply the parameters. For a more trivial (and perhaps more easily comprehended) example, lets take a function called 'add' that adds two numbers:
let add = (x, y) => x + y;
Not very interesting. But lets break it up so it can take the first number and return a function that takes the second:
let add = x => y => x + y;
let add3 = add(3);
let seven = add3(4); // 7
This may not seem like a big win for our add function, but you started with a much more reasonable real-world example. Additionally, rather than currying manually it is possible (and desirable) to use a curry function that does it for you, many popular libraries (lodash, underscore, ramda) implement curry for you. An example using Ramda:
let add = R.curry((x, y) => x + y);
let add3 = add(3);
let five = add3(2);
let also5 = add(3, 2);
let still5 = add(3)(2); // all are equivalent.
This answer is for those who still have some doubts in double arrow functions. Lets dig deep into it.
const doubleArrowFunc = param1 => param2 => {
console.log('param1', param1);
console.log('param2', param2);
}
If you call this function
const executeFunc = doubleArrowFunc('Hello');
If you print executeFunc in console you'll get an output like this
ƒ (param2) {
console.log('param1', param1);
console.log('param2', param2);
}
Now this is like a half executed code. If you wanna execute it fully, you've to do it like this
executeFunc('World');
//And the output will be
param1 Hello
param2 World
If you want even more understanding. I can execute the same without arrow function
function doubleArrowFunc(param1) {
return function innerFunction(param2) {
console.log('param1', param1);
console.log('param2', param2);
}
}