Why Doesn't My Arrow Function Return a Value

Why doesn't my arrow function return a value?

When you use the function body version of an arrow function (with {}), there is no implied return. You have to specify it. When you use the concise body (no {}), the result of the body expression is implicitly returned by the function.

So you would write that either with an explicit return:

const f = arg => { return arg.toUpperCase(); };
// Explicit return ^^^^^^

or with a concise body:

const f = arg => arg.toUpperCase();

Examples:

const f1 = arg => { return arg.toUpperCase(); };

console.log(f1("testing"));

const f2 = arg => arg.toUpperCase();

console.log(f2("testing"));

Does the arrow function have to always return a value?

No, (arrow) functions don't have to return anything but when function is not supposed to be void (i.e return value is expected), it's a good practice to return from every path/return some kind of default value if every other path fails.

const getCookie = name => {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length == 2) {
return parts
.pop()
.split(';')
.shift();
}

// default return, for example:
return false;
};

Why is my arrow function returning `undefined`?

Arrow functions support two different styles of bodies: expressions and blocks.

If a single expression is provided (e.g. a + b) without braces { } around it, that expression is automatically returned:

const add = (a, b) => a + b

If a block enclosed by { } is provided, it works like a regular function body and requires a dedicated return statement to return a value:

const add = (a, b) => {
return a + b
}

Single-expression bodies are often used to write simple functions in a concise way which execute one operation or condition, as in the following examples:

if (users.every(user => user.age >= 18)) { /* ... */ }

const emails = users.map(user => user.email)

const titleCased = string.replace(/\b\w/g, s => s.toUpperCase())

// in the following example, the return value is irrelevant
setTimeout(() => doStuff(1, 2, 3), 1000)

In most other cases, especially if you want to have multiple statements, loops or conditions in your function body, a block is used.

Note that you can have a function body spanning multiple lines even without a block if it is still a single expression, but if you would like to turn it into a block for readability reasons, you must not forget to add return (unless your function isn't supposed to return anything).

Now, this is the reason why your add function is returning undefined - it neither has a single-expression body (the { } make it a block) nor does it have any return statement in its body. So, what happens is that a + b is evaluated, but the result isn't used for anything - it is thrown away and execution continues, reaching the end of the function and returning without any return value since none was given, i.e. returning undefined.


In the React case, the problem is the same. You are embedding the return value of a .map call, which should be an array of further content to render, but because your callback is not returning any value, you are mapping the items to several undefined values and rendering that at the end.

There is another twist here though: you may often need multiple lines in the element(s) that you return from a function like a map callback, but you will find that neither of the following two options looks quite clean:

<ul>
{list.map(item => <li>
<a href="{item.url}">{item.name}</a>
</li>)}
</ul>

<ul>
{list.map(item => {
return <li>
<a href="{item.url}">{item.name}</a>
</li>
})}
</ul>

Instead, what is usually done is enclosing the expression in parentheses ( ). It is a still a single expression at the end, avoiding the need for an extra return statement, but is a lot nicer to work with:

<ul>
{list.map(item => (
<li>
<a href="{item.url}">{item.name}</a>
</li>
))}
</ul>

For more information about arrow functions in general, see here. To read about other differences between arrow functions and regular functions (such as different behavior of this), see here.

How to fix Expected to return a value in arrow function with reactjs?

Line 26:64: Expected to return a value in arrow function array-callback-return

Since you do not care about returning a value from the arrow function and you are not using the array returned by the map(), you should be using forEach() function instead.

componentDidMount() {
if(Object.keys(this.props.praticiens).length>0)
Object.keys(this.props.praticiens).forEach((praticien) => {
if(this.props.praticiens[praticien].identifiant_user === getUrlParams(window.location.hash).identifiant_user)
this.setState({
praticien:this.props.praticiens[praticien].id_user
})
})
}

handleChangePraticien = (praticien) => {
this.setState({ praticien }, () => {
Object.keys(this.props.praticiens).forEach((praticien) => {
if(this.state.praticien === this.props.praticiens[praticien].id_user)
this.props.selectPraticienFunction(this.props.praticiens[praticien].identifiant_user);
})
})

How do I fix Expected to return a value at the end of arrow function warning?

The warning indicates that you're not returning something at the end of your map arrow function in every case.

A better approach to what you're trying to accomplish is first using a .filter and then a .map, like this:

this.props.comments
.filter(commentReply => commentReply.replyTo === comment.id)
.map((commentReply, idx) => <CommentItem key={idx} className="SubComment"/>);

Why can't I return an arrow function?

Arrow functions doesn't have the arguments object, instead you can use the rest parameter syntax (...) like this:

var square = (a) => a * a;

var callAndLog = (func) => {

return ((...args) => {

var res = func.apply(undefined, args);

console.log("Result is: " + res);

return res;

})

};

var squareAndLog = callAndLog(square);

squareAndLog(5);

Expected to return a value at the end of arrow function' - Is there another way to do this other than filter?

There is a default branch you haven't provided a return value for.

                if (searchTerm === '') {
return item;
} else if (
return item.title
.toLowerCase()
.includes(searchTerm.toLowerCase()) ||
playlist.description
.toLowerCase()
.includes(searchTerm.toLowerCase())
) {
return playlist;
} else {
// return something;
}

Furthermore, item and playlist seem to be objects, which are not useful values for filtering an array since you should return a Boolean value. You might mean...

?.filter(item => {
if (searchTerm === '') {
return true;
} else if (
item.title
.toLowerCase()
.includes(searchTerm.toLowerCase()) ||
playlist.description
.toLowerCase()
.includes(searchTerm.toLowerCase())
) {
return true;
} else {
return false;
}
})

If it's the case, the function can be simpified to...

?.filter(item => (
searchTerm === '' ||
item.title
.toLowerCase()
.includes(searchTerm.toLowerCase()) ||
playlist.description
.toLowerCase()
.includes(searchTerm.toLowerCase())
);


Related Topics



Leave a reply



Submit