I have the following line of code working on my code, but eslint is getting me an error back.
this.data.forEach(el => el.value === newValue ? el[column] = newValue[column] : el)
This gives me the following error:
no-return-assign: Arrow function should not return assignment.
In this question it states I would solve the problem by simply surrounding everything after => in curly braces like this:
this.data.forEach(el => { el.value === newValue ? el[column] = newValue[column] : el })
However, this is now causing the following error:
no-unused-expression: Expected an assignment or function call and instead saw an expression.
Any clues on how to solve this?
The reason you're getting these kinds of warnings is because it's confusing to put imperative code inside an expression. Your code is equivalent to something like this, which is much more readable:
this.data.forEach(el => {
if (el.value === newValue) {
el[column] = newValue[column];
return newValue[column];
else {
return el;
}
});
It's worth noting that the return value of a callback in forEach is ignored, so your code actually probably does something different to what you intended. If the assignment statement is all you wanted, you can do this:
this.data
.filter(el => el.value === newValue)
.forEach(el => {
el[column] = newValue[column];
});
Related
The reason I say language agnostic is that I would like a small, self contained implementation that determines if the outermost scope in a string containing JavaScript is a function or not. I've looked at the MDN for guidance on the possible forms of declaring functions, but unfortunately wasn't able to find any comprehensive examples for all the ways functions can be defined in JS.
Here's a few different test cases the implementation should be able to handle:
// yes
function (){}
//yes
() => p
//yes
((g) => p)
//yes
(g => p)
//no
(()=>p)()).call()
//no
a = function (){
console.log()
{
//no
g=() => p
I've thought about trying to construct a regex to look for this, but I'm not sure I've covered every case, and I haven't found any sort of corpus of example JS functions, or even if a pure regex approach would be the best way to handle this.
You can use Acorn to parse the Javascript. If parsing is successful, and the body is composed only of a single item, and that item is a FunctionDeclaration or ArrowFunctionExpression, the test passes:
const test = (str) => {
console.log(str);
try {
const { body } = acorn.parse(str);
if (body.length > 1) throw new Error();
const [item] = body;
if (item.type === 'FunctionDeclaration' || (item.type === 'ExpressionStatement' && item.expression.type === 'ArrowFunctionExpression')) {
console.log('Pass');
} else {
console.log('invalid');
}
} catch(e) {
console.log('invalid');
}
};
// function (){}
test(`function foo() {}`);
test(`() => p`);
test(`((g) => p)`);
test(`(g => p)`);
test(`(()=>p)()).call()`);
test(`a = function (){
console.log()
{`);
test(`g=() => p`);
<script src="https://cdnjs.cloudflare.com/ajax/libs/acorn/7.1.1/acorn.min.js"></script>
Is there a way to shorten this fragment of code?
const result = getResult();
if (!result) {
return;
}
// Work with result
I keep having lots of these in my code and would love to do something like:
const result = getResult() || return;
// Work with result
EDIT:
I only want convertable inputs to be persisted.
const parseInput = (input: string): void => {
const convertedInput = convert(input);
if (!convertedInput) {
return;
}
persist(convertedInput);
}
I know I could call the converter twice. But I want to avoid that:
const parseInput = (input: string): void => {
if (!convert(input)) {
return;
}
persist(convert(input));
}
Your code is as good as it gets, however, if you want to experiment a bit with the functional style, you can wrap the value into a "monad", which would invoke attached functions only if the value is non-zero. Here's a toy implementation:
function maybe(x) {
return {
value: x,
apply(fn) {
if (this.value)
this.value = fn(this.value)
return this;
}
}
}
With this maybe, your example would look like:
const parseInput = input => maybe(convert(input)).apply(persist)
See the Oliver's answer for a more serious approach.
You can do this
const result = "default value" || getResult();
If getResult is null or not defined then you'll get result as "default value". If that's what you want
function getResult() {
return null;
}
const result = "okay" || getResult();
console.log(result)
And when getResult is not defined you get
const result = "okay" || getResult();
console.log(result)
Basically, the syntax is
null || undefined || null || 0 || "okay" || "defined" // "okay"
It goes from left to right and picks the most relevant value
I don't really know if this answer will give you something that you'll be happy with, but it seems to me to present a potential solution to the problem of handling unknown results.
Maybes are structures which have this kind of checking built-in. the .map() below will not be called if there is no value in the Maybe, so the code which consumes it does not need to check whether a value is present.
This does mean that you have to change the way in which you handle these values however, and, unless you want to write your own, it means using a library. As such this is hardly an ideal solution, but I hope it gives an option at least.
const { None, Some } = Monet;
const getResult = () => Math.random() > 0.5
? None()
: Some(1);
const test = getResult()
.map(x => x + 2);
console.dir(test.val);
<script src="https://cdn.jsdelivr.net/npm/monet#0.9.0/dist/monet.min.js"></script>
My eslint version is 4.18.2, it would give a warning like this:
Unexpected unnamed function
Expected an assignment or function call and instead saw an expression
When defining functions in such a way:
const farmerIds = a.reduce((function (hash) {
return function (prev, curr) {
!hash[curr.farmerId] && (hash[curr.farmerId] = prev.push(curr));
return prev;
};
}(Object.create(null))), []);
These are two different issues…
Unexpected unnamed function
This is, as pointed out by Constantin, the ESLint rule func-names.
If you don't want to disable this rule, you can either use names for your functions, like so:
const farmerIds = a.reduce((function reducer(hash) {
return function fn(prev, curr) {
!hash[curr.farmerId] && (hash[curr.farmerId] = prev.push(curr));
return prev;
};
}(Object.create(null))), []);
Or, and this I would recommend personally, use arrow functions:
const farmerIds = a.reduce(
(hash => {
return (prev, curr) => {
!hash[curr.farmerId] && (hash[curr.farmerId] = prev.push(curr));
return prev;
};
})(Object.create(null)),
[]
);
Expected an assignment or function call and instead saw an expression
ESLint is complaining about this line, which is indeed an expression, not an assignment or function call:
!hash[curr.farmerId] && (hash[curr.farmerId] = prev.push(curr));
You can rewrite it as an if statement:
if (!hash[curr.farmerId]) {
hash[curr.farmerId] = prev.push(curr);
}
Fixing both
Putting the code examples above together, this code should run without ESLint complaining:
const farmerIds = a.reduce(
(hash => (prev, curr) => {
if (!hash[curr.farmerId]) {
hash[curr.farmerId] = prev.push(curr);
}
return prev;
})(Object.create(null)),
[]
);
Note that I've also removed the curly braces around the body of the first arrow function, which is a nice additional feature of arrows to keep the code more concise.
Another simple way is give the underscore as the function name. For example:
const farmerIds = a.reduce((function _(hash) {...}(...);
If we need to export without declaring, it can be used as below
export default () => {
// your code goes here
}
i have this button
<button
className="waves-effect waves-light btn btn-secondary has-icon"
onClick={() => {
const idSelected = []
const itemSelected = this.state.clientItemUser.filter((i, row) => {
if (this.props.listTableCheckedItems.indexOf(row) === -1) {
idSelected.push(i.clientid)
return i
}
})
const { setTableCheckedItems } = this.props
console.log('itemSelected > ', itemSelected)
this.setState({ clientItemUser: itemSelected, clientIdItemUser: idSelected })
setTableCheckedItems([])
}}
>
it works and do what is suppoused to do, but i want to get rid of this warning "Expected to return a value at the end of arrow function array-callback-return"
it says the problem is on the line const itemSelected = this.state.clientItemUser.filter((i, row) => i really want to learn how to solve this warnings since its not the only place that it appears,i belive that understanding this one im going to be able to figure out the other ones, thanks for your time and help
i have looked another similar problems on stack but they dont seems to be the same as mine
You're only returning something in the case of row being in this.props.listTableCheckedItems.
There are a couple issues here.
1: You need to return something if that is not true.
if (this.props.listTableCheckedItems.indexOf(row) === -1) {
idSelected.push(i.clientid)
return i
} else {
return ...
}
2: Your filter callback will return falsy for the first element in the list, since i is 0. Unless this is intended, you should return true or false.
if (this.props.listTableCheckedItems.indexOf(row) === -1) {
idSelected.push(i.clientid)
}
return this.props.listTableCheckedItems.indexOf(row) === -1
I need to replace imagesrc with the value stored in this object. However when I run:
if(data['results'][res]['entities']['media']["0"]["media_url"]) {
imagesrc = data['results'][res]['entities']['media']["0"]["media_url"];
}
I get the error:
Cannot read property '0' of undefined
How can I run my condition so that I don't get errors if something is undefined?
if (data['results'][res]['entities']['media']["0"] == undefined
|| data['results'][res]['entities']['media']["0"] == null) {
...
}
you can place your code inside a try catch block and examin error message.
You could write a function that walks the object tree and returns undefined as soon as it hits an undefined property:
function safeGetData(obj, names)
{
for (var i = 0; i < names.length; ++i) {
if (typeof obj === "undefined") {
return undefined;
}
obj = obj[names[i]];
}
return obj;
}
You can use it like this:
var imagesrc = safeGetData(data,
["results", res, "entities", "media", "0", "media_url"]);
I’m a fan of using short circuit evaluation for these kinds of situations:
items && items[val] && doSomething(items[val])
Some people might be repulsed by this, but I think it’s a nice and readable way to express something that should only be evaluated if certain conditions are met.
In this case, we’re actually chaining two short circuit evaluations. First, we determine whether items has a defined value. If it undefined, then the rest of the expression is moot, so we won’t even bother to evaluate it. AND if it is defined, then let’s check for the existence of some property that we’re interested in. If it’s undefined, then bail out. AND if it’s true, we can go ahead and evaluate the rest of the expression.
I think it’s a lot easier to reason through at a glance than:
if (items) {
if (items[val]) {
doSomething(items[val])
}
}
Ternary operators work similarly:
items
? items[val]
? doSomething(items[val])
: alert(‘The property “‘ + val + ‘“ has not yet been defined.’)
: alert(‘You have not yet defined any items!’)
It's an old topic, I know. It's just to add my 2 cents.
I'm definitely not a javascript "guru", but here's one of my old attempts. It relies upon a couple of new ecmascript 6 features and it's going to approach the problem in a more "functional" way:
const prop = (...arr) => obj => arr.reduce((acc, v) => acc && acc.hasOwnProperty(v) ? acc[v] : undefined, obj)
And some tests in order to show how it should work:
describe('unit - prop', () => {
const event = {
record: {
sns: {
subject: 'Hello',
message: '<div>Welcome!</div>'
}
}
}
it('property exists', done => {
const value = prop('record', 'sns', 'subject')(event)
expect(value)
.to
.be
.equal('Hello')
done()
})
it('property does not exist', done => {
const value = prop('record', 'bad', 'subject')(event)
expect(value)
.to
.be
.undefined
done()
})
})
Does it make sense?