1

I have an array

errorPriority: string[] = ['shippingError', 'paymentInfoError', 'generalError'];

I need a function call to be looped on every element of array, but somehow after executing function for first element 'shippingError', the loop stops. Below is the function call

this.errorPriority.every(this.getErrorData);

And the function that is executed

getErrorData = (value: string): void => {
    if (eval(this.objectPath[value as keyof ObjectPath]) && eval(this.objectPath[value as keyof ObjectPath]).length)
      this.checkoutState.errors[value] = eval(this.objectPath[value as keyof ObjectPath]);
  }

It sometimes, works on array element, but mostly stops after first element, Am I missing something, please help

I expect function should be looped on every array element

jigfox
  • 18,057
  • 3
  • 60
  • 73
Manoj G
  • 35
  • 5
  • 3
    Use `forEach` and not `every`. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach – R. Richards Nov 23 '22 at 13:16
  • I can change, but any reason why above scenario happens? – Manoj G Nov 23 '22 at 13:18
  • are you sure you are understanding every? please check https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every – programandoconro Nov 23 '22 at 13:18
  • 1
    Please read the documentation for every. You do not return anything so it returns undefined. Undefined is not truthy. – epascarello Nov 23 '22 at 13:20
  • Also using eval is not a great practice. Usually there is better ways to do things. – epascarello Nov 23 '22 at 13:21
  • Understood the return part, @epascarello - do you any suggestion for eval, because that`s a string I have to refer for a path – Manoj G Nov 23 '22 at 13:22
  • https://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-and-arrays-by-string-path – epascarello Nov 23 '22 at 13:25
  • every function works differently, it is used ex. to check if all values of the array, let's say have value and not undefined, thats the common case. So you pass a callback to it that returns a boolean and in case if the first item in the array fails on check, there is no reason to continue looping thru the rest of the items and that's why it quits. You should use something different for your case, forEach as it was mentioned above could be a better choice – JSEvgeny Nov 23 '22 at 13:28

3 Answers3

2

The every() method tests whether all elements in the array pass the test implemented by the provided function. It returns a Boolean value.

Source

this means Array#every() checks if every item in array meets the criteria tested by given function, and that means the given function should return a boolean value. Since your function does return void or in javascript undefined, this will be interpreted as false. And because every returns true only if all elements return a truthy value, the iteration can be aborted after the first falsy value.

to run your code on every item you need to use forEach

jigfox
  • 18,057
  • 3
  • 60
  • 73
0

You are using every function, it will just test if ALL elements of your array successfully pass your function. So the given function MUST return a boolean (true or false) but you are returning void. try to return "true" if your condition is successfull

getErrorData = (value) => {
    if (eval(this.objectPath[value]) && eval(this.objectPath[value]).length) {
      this.checkoutState.errors[value] = eval(this.objectPath[value]);
      return true;
    }
  }
Paul-Marie
  • 874
  • 1
  • 6
  • 24
  • changed this way, getErrorData = (value: string): ObjectPath => { if (eval(this.objectPath[value as keyof ObjectPath]) && eval(this.objectPath[value as keyof ObjectPath]).length) this.checkoutState.errors[value] = eval(this.objectPath[value as keyof ObjectPath]); return eval(this.objectPath[value as keyof ObjectPath]); }; – Manoj G Nov 23 '22 at 13:25
  • this will still abort after first element not matching the criteria, `forEach` is the safe way to hit *every* item in the array – jigfox Nov 23 '22 at 13:29
-1

from the MDN documentation the definition of array.every() is

every() method tests whether all elements in the array pass the test implemented by the provided function. It returns a Boolean value.

so array.every returns a boolean. in your code you don't return anything. if the condition is true, you only assign a new property.

the following should work:

   getErrorData = (value) => {
    if (eval(this.objectPath[value]) && eval(this.objectPath[value]).length) {
      this.checkoutState.errors[value] = eval(this.objectPath[value]);
      return true;
    }
      return false
    }
laian
  • 270
  • 2
  • 5
  • this will not hit every item all the time, op asked for a way to run method on every item – jigfox Nov 23 '22 at 13:30
  • the `return false` is pointless because return nothing means return `undefined` (a falsy value interpreted as `false`), so don't bother you to return `false` – Paul-Marie Nov 23 '22 at 13:37
  • @Paul-Marie you're right. he does not need to explictly return `false`, but personally I like to be as explicit as I can :) – laian Nov 23 '22 at 15:13
  • @laian maybe I missunderstood "I expect function should be looped on every array element" ‍♂️ – jigfox Nov 23 '22 at 16:09