1

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.

1
  • objects do not implement the iterable protocol. you have to do something like Object.values(this.state).forEach(current => { ... }); Commented Nov 6, 2018 at 1:38

5 Answers 5

2

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)

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

Comments

2

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

Comments

0

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

Comments

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

// In your code replace state with this.state
let emptyArrays = Object.values(state).reduce(
  (acc, current)=> ( !current.length? ++acc: acc),
  0
)

console.log(emptyArrays)

Comments

0

I am working something similar, so I used:

Object.keys(state.amenities).length

it worked and it is way simpler I think.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.