Count arrays with values in state in React

4058 views reactjs
7

I currently have the following state:

this.state = {
  selectProduct: [somearrayValues],
  quantityProduct: [],
  colorsProduct: [somearrayValues],
  stockProduct: [somearrayValues],
  turnaroundProduct: [],
  coatingProduct: [],
  attributeProduct: [somearrayValues],
  attributeMetaProduct: [somearrayValues],
}

I do a fetch call to fill up the arrays with the needed data. From here I need to get a count of Arrays that actually contain a value. I'm lost as how to accomplish this.

I first was trying to get to the state with a for each loop but I haven't even got passed this point:

let dropdownArrays = ...this.state;
dropdownArrays.forEach(function(element) {
  console.log(element);
});

This gives me an error when babel attempts to compile. I then tried the below, which returns nothing.

let dropdownArrays = [...this.state];
dropdownArrays.forEach(function(element) {
  console.log(element);
});

I know I'm missing it so any help would be greatly appreciated.

answered question

objects do not implement the iterable protocol. you have to do something like Object.values(this.state).forEach(current => { ... });

4 Answers

6

Perhaps you could use the Object#values() method to access the array objects (ie the values) of the state, and then count the number of non-empty arrays like so:

// Pre-filled arrays with some values. This solution would work
// regardless of the values you populate the arrays with
const state = {
  selectProduct: [1,2,3,4],
  quantityProduct: [],
  colorsProduct: [4,5,6,7],
  stockProduct: [1,2],
  turnaroundProduct: [],
  coatingProduct: [],
  attributeProduct: [6,7,8,9,10],
  attributeMetaProduct: [5,4,6],
}

const result = Object.values(state)
.filter((array) => array.length > 0)
.length;

console.log('Number of arrays in state with values (non-empty)', result)

posted this
3

you can try with https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

Object.entries(...this.state)[1].reduce((accumulator, currentValue) => accumulator + currentValue.length, 0)

Bear in mind that to use ...this.state you need https://babeljs.io/docs/en/babel-plugin-proposal-object-rest-spread

posted this
9

Because state is an object, you instead could use a couple different options. You could do

this.state.values, which will return an array of the values in state.

this.state.values.forEach(function(value) {
    console.log(value);
});

Or you could use this.state.entries, which will return an array of the key, value.

this.state.entries.forEach(function(entry) {
    console.log(entry);
    // expected output [key, value]
});

Lastly as you appear to already be attempting to use destructuring, you can also destructure the result.

this.state.entries.forEach(function([key, value]) {
    console.log(key);
    console.log(value);
});

posted this
0

var state = {
  selectProduct: [1,2,3,4],
  quantityProduct: [],
  colorsProduct: [4,5,6,7],
  stockProduct: [1,2],
  turnaroundProduct: [],
  coatingProduct: [],
  attributeProduct: [6,7,8,9,10],
  attributeMetaProduct: [5,4,6],
}

let emptyArrays = Object.values(state).reduce(
  (acc, current)=> ( !current.length? ++acc: acc),
  0
)

console.log(emptyArrays)

posted this

Have an answer?

JD

Please login first before posting an answer.

Ads

Categories