Oliver D
Oliver D

Reputation: 2889

How can I get a total when iterate an array?

I got an array of an object from the Database and inside every object.

I have a price and count I need to get every item price and after that should I calculate the total price of all items and set it into state.

Here's structure array I got from DB:

state = {
  TotalCountTools: null, // here will get all the total price for every item
  toolsUsed: [
      {
        id: 1,
        name: 'tool 1',
        price: 10,
        count: 3,
      },
      {
        id: 2,
        name: 'tool 2',
        price: 5,
        count: 3,
      },
      {
        id: 3,
        name: 'tool 3',
        price: 1,
        count: 2,
      },
    ],
}

Here's what I tried and it's failed:

renderToolsUsed = () => {
    let {TotalCountTools} = this.state;
    return this.state.toolsUsed.map(({name, id, price, count}, i) => {
      let TotalCount = count * price;
      console.log(TotalCount);
      this.setState({TotalCountTools: TotalCount}, () =>
        console.log(TotalCountTools), // so in every iterate that will set a state and that's wrong i know 
      );

      return (
        <>
          <View>
            <Text key={id}>{name}</Text>
          </View>

          <View>
            <Text key={id}>{price}</Text>
          </View>

          <View>
            <Text key={id}>{count}</Text>
          </View>
       </>
      );
    });
  };

EDIT

after I see all answers I just follow as @Shubh says to get total price so i make another function just to get the total price

 getTotalPrice = () => {
    let total = this.state.toolsUsed.reduce((acc, {price, count}) => {
      acc = acc + price * count;
      return acc;
    }, 0);
    this.setState({totalPriceTools: total}, () =>
      console.log(this.state.totalPriceTools),
    );
  };

and inside a UI i added it

 render() {
  return (
      <View style={{flex: 1}}>
         {this.renderToolsUsed()}
   <>
              <Text
                style={{
                  paddingBottom: 5,
                  fontWeight: '700',
                  fontSize: 17,
                  color: '#9F9F9F',
                  marginLeft: 20,
                }}>
               Total Price:
              </Text>
              {this.getTotalPrice()} // I don't know how can i call this function so i added it here and that's wrong insted of it should i write {this.state.totalPriceTools}
            </>
 )
}

UI

"I add a flag in the state after getting a total price I want to update it and used it in other View" UI

EDIT 2

I want after render the tools item "map finish" invoke other function "calculate the total prices"

  renderToolsUsed = () => {
    const {toolsUsed} = this.state;
    const prom = toolsUsed.map(({name, id, price, count}) => {
      return (
        <View style={styles.tools}>
          <View style={styles.toolsItem}>
            <Text key={id}>{name}</Text>
          </View>
          <View style={styles.toolsItem}>
            <Text key={id}>{price}</Text>
          </View>
          <View style={styles.toolsItem}>
            <Text key={id}>{count}</Text>
          </View>
        </View>
      );
    });
    return Promise.all(prom).then(() => this.getTotalPrice());
  };


  getTotalPrice = () => {
    let total = this.state.toolsUsed.reduce((acc, {price, count}) => {
      acc = acc + price * count;
      return acc;
    }, 0);
    this.setState({totalPriceTools: total}, () =>
      console.log(this.state.totalPriceTools),
    );
  };

I got this error

Invariant Violation: Objects are not valid as a React child (found: object with keys {_40, _65, _55, _72}).

Upvotes: 1

Views: 1006

Answers (3)

Muhammad Murad Haider
Muhammad Murad Haider

Reputation: 1477

What i have understood is: you want to calculate total price for every item i.e. price*count, in the array and then sum all calculated prices and set the state. If it is so then you can create a function lets say 'CalculateEachOrderPrice()' in which you will iterate through the array and calculate total amount for each item and simply push the calculated value in an array e.g. prices []. After array is iterated (loop ends), calculate the sum for prices array and set the state. Call CalculateEachOrderPrice() function on ComponentDidMount() or success callback of the method that is returning you the object from database.

Upvotes: 0

Shubham Dixit
Shubham Dixit

Reputation: 1

You can use array.reduce() for the job;

let toolsUsed = [{
    id: 1,
    name: 'tool 1',
    price: 10,
    count: 3,
  },
  {
    id: 2,
    name: 'tool 2',
    price: 5,
    count: 3,
  },
  {
    id: 3,
    name: 'tool 3',
    price: 1,
    count: 2,
  },
]
let total = toolsUsed.reduce((acc, {
  price,
  count
}) => {
  acc = acc + price * count;
  return acc;
}, 0)

console.log(total)
// Or particular total for element
toolsUsed.forEach(ele => {
  ele["total"] = ele.price * ele.count;
})
console.log(toolsUsed)

Upvotes: 1

Yaman KATBY
Yaman KATBY

Reputation: 2023

As I understand this is what you are searching for

const tools = [{
    id: 1,
    name: 'tool 1',
    price: 10,
    count: 3,
  },
  {
    id: 2,
    name: 'tool 2',
    price: 5,
    count: 3,
  },
  {
    id: 3,
    name: 'tool 3',
    price: 1,
    count: 2,
  },
]

const result = {};
tools.forEach((tool) => {
  result[tool.id] = tool.price * tool.count;
})

console.log(result)

Upvotes: 1

Related Questions