0
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 *ngIf="test1 || test2 || test3">
            DISPLAY ERROR
        </div>

I'm not sure it this is the correct way.

2
  • Are you trying to display the specific errors if there are any? Commented Jan 11, 2022 at 8:55
  • 1
    Please add context to your question. What do you need that for and why typescript ? Together with this if attribute in HTML it looks like angular .. correct ? Then there is a little trick you oversaw 😉️ Commented Jan 11, 2022 at 16:04

2 Answers 2

3

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);

Sign up to request clarification or add additional context in comments.

Comments

-1

TL;DR: Can use ['test1', 'test3'].some(field => nonEmptyErrors(data[field])). See how functional JS-patterns work in different solutions.

Chaining conditions

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 can be done more flexible using the functional some(predicate) test in JavaScript.

I want to explain some functional ingredients before showing you the solving recipe.

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 following functional ingredients

  1. nonEmptyErrors: use a lambda predicate to filter elements
  2. map, reduce and some as shortcuts (syntactic sugar)

to:

  1. hasErrors(data): a convenient function which returns a boolean
  2. test selected properties ['test1', 'test3'] only

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'},
  ]
};

// (0) data: tests with array of errors as string, some empty

// (1) define a filter lambda (can be used as function)
let nonEmptyErrors = arr => arr.filter(el => el.error !== '');

// (2) count specific elements with map-reduce
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;
console.log("countNonEmptyErrors", countNonEmptyErrors);


// (3) reuse the filter as predicate in a convenient function
function hasErrors(data) {
  return Object.values(data).some(nonEmptyErrors);
}
console.log("data has errors?", hasErrors(data));

// (4) filter selected properties of an object
console.log("test1, test3 | any errors: ", 
  ['test1', 'test3'].some(field => nonEmptyErrors(data[field]))
);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.