const data = {
test1: [
{error: ''},
{error: ''},
],
test2: [
{error: ''},
{error: 'theres an error in this field'},
{error: 'theres an error here'},
],
test3: [
{error: ''},
{error: 'theres an error'},
{error: 'theres an error here'},
]
};
how to check if the array has an error. which it should display an error message.
for example I have a <div> with condition and the data return true once there's only one true it will display the error message.
here's my code
const test1 = data.test1.some(x => x.error !== '');
const test2 = data.test2.some(x => x.error !== '');
const test3 = data.test3.some(x => x.error !== '');
<div if="test1 || test2 || test3">
DISPLAY ERROR
</div>
I'm not sure it this is the correct way.
CodePudding user response:
You can use Object.values to get an array of the values of the properties of the object and use some, and within the some callback you can return the result of your some calls on the value if it's an array:
const hasError = Object.values(data).some(value => Array.isArray(value) && value.some(x => x.error));
If you know all the properties are these testX properties, you can drop the Array.isArray part.
Live Example:
const dataWithError = {
test1: [
{error: ''},
{error: ''},
],
test2: [
{error: ''},
{error: 'theres an error in this field'},
{error: 'theres an error here'},
],
test3: [
{error: ''},
{error: 'theres an error'},
{error: 'theres an error here'},
]
};
const dataWithoutError = {
test1: [
{error: ''},
{error: ''},
],
test2: [
{error: ''},
{error: ''},
{error: ''},
],
test3: [
{error: ''},
{error: ''},
{error: ''},
]
};
const dataWithErrorHasError = Object.values(dataWithError).some(
value => Array.isArray(value) && value.some(x => x.error)
);
console.log(`dataWithError:`, dataWithErrorHasError);
const dataWithoutErrorHasError = Object.values(dataWithoutError).some(
value => Array.isArray(value) && value.some(x => x.error)
);
console.log(`dataWithoutError:`, dataWithoutErrorHasError);
Or for just specific properties from data, build the array directly:
const hasError = [data.test1, data.test2, data.test3].some(test => test.some(x => x.error));
Live Example:
const dataWithError = {
test1: [
{error: ''},
{error: ''},
],
test2: [
{error: ''},
{error: 'theres an error in this field'},
{error: 'theres an error here'},
],
test3: [
{error: ''},
{error: 'theres an error'},
{error: 'theres an error here'},
]
};
const dataWithoutError = {
test1: [
{error: ''},
{error: ''},
],
test2: [
{error: ''},
{error: ''},
{error: ''},
],
test3: [
{error: ''},
{error: ''},
{error: ''},
]
};
const dataWithErrorHasError = [dataWithError.test1, dataWithError.test2, dataWithError.test3].some(test => test.some(x => x.error));
console.log(`dataWithError:`, dataWithErrorHasError);
const dataWithoutErrorHasError = [dataWithoutError.test1, dataWithoutError.test2, dataWithoutError.test3].some(test => test.some(x => x.error));
console.log(`dataWithoutError:`, dataWithoutErrorHasError);
CodePudding user response:
In test1 || test2 || test3 your are chaining tests with boolean OR ||. The boolean OR is short-circuiting, means the first true in evaluation of this chain wins. The same as some(predicate) test in JavaScript.
Functional Basics
Arrays in pipelines: Filter, Map, Reduce
JavaScript uses filter to find any objects that satisfy the predicate.
Can combine it with map, reduce as chained methods to build a data-pipeline. This approach is often called "streaming".
Objects to arrays
First you have to get a stream from your object data.
This can be done using factory methods:
Functionals applied
Let's use the functional-basics explained above and build a chained pipeline to test, if your data object has errors.
Finally, we combine the syntactic sugar (e.g. shortcut method some) with a lambda predicate in a function hasErrors(data) which returns a boolean.
const data = {
test1: [
{error: ''},
{error: ''},
],
test2: [
{error: ''},
{error: 'theres an error in this field'},
{error: 'theres an error here'},
],
test3: [
{error: ''},
{error: 'theres an error'},
{error: 'theres an error here'},
]
};
// define a filter lambda
let nonEmptyErrors = arr => arr.filter(el => el.error !== '');
// data: tests with array of errors as string, some empty
let countNonEmptyErrors = Object.entries(data)
.map(([key, value]) => {
let errors = nonEmptyErrors(value);
console.log(key, errors.length);
return errors;
})
// sum/count elements
//.reduce((acc, elem)=>{acc = elem.length; return acc;}, 0);
.flat().length;
// reuse the filter as predicate
function hasErrors(data) {
return Object.values(data).some(nonEmptyErrors);
}
console.log("countNonEmptyErrors", countNonEmptyErrors);
console.log("data has errors?", hasErrors(data));
