Youssef
Youssef

Reputation: 645

for loop logic fail to detect if item exists in array (javascript)

I am looking to check if a product id already exists in memory so I only update the quantity of it, my data is an array looking like [{ id: data.id, price: data.price, qty: 1 }]

My code is this function

storeProduct = async (data) => {
    this.setState({ found: null })
    try {
      const value = await AsyncStorage.getItem('cart')
      if (value !== null) {
        var products = JSON.parse(value)
        for (let x in products) {
          if (products[x].id === data.id) {
            this.setState({ found: true })
          } else {
            this.setState({ found: false })
          }
        }
      } else {
        await AsyncStorage.setItem(
          'cart',
          JSON.stringify([{ id: data.id, price: data.price, qty: 1 }])
        )
      }
      if (this.state.found === false) {
        var obj = { id: data.id, price: data.price, qty: 1 }
        await AsyncStorage.setItem('cart', JSON.stringify([...JSON.parse(value), obj]))
      }
    } catch (error) {
      this.setState({ error: error })
    }
  }

it does work but only when testing on same product, when I click on another product and then go back to first one it concat that id to the array and I get 2 similar ids. It's weird so I am not sure what logic I should use, I was inspired by the example below using redux:

if(action.type === ADD_TO_CART){
      let addedItem = state.items.find(item=> item.id === action.id)
      //check if the action id exists in the addedItems
     let existed_item= state.addedItems.find(item=> action.id === item.id)
     if(existed_item)
     {
        addedItem.quantity += 1 
         return{
            ...state,
             total: state.total + addedItem.price 
              }
    }
     else{
        addedItem.quantity = 1;
        //calculating the total
        let newTotal = state.total + addedItem.price 
        
        return{
            ...state,
            addedItems: [...state.addedItems, addedItem],
            total : newTotal
        }
        
    }
}

Upvotes: 1

Views: 360

Answers (2)

Sagar Darekar
Sagar Darekar

Reputation: 1014

I think problem might be inside your for loop, its getting executed for multiple items. For example -

let products = [{ id: "id", price: "price", qty: 1 },{ id: "id2", price: "price2", qty: 12 }]

for (let x in products) {
  if (products[x].id === data.id) {
         this.setState({ found: true })
    } else {
         this.setState({ found: false })
    }
}

For first product, it will set found equal to true, and again for the second iteration, it will go into else and set found equal to false. I think maybe because of this you are getting a duplicate product. Instead of for loop to check if element exists or not you can use findIndex method of array -

let index = products.findIndex((element)=> element.id === data.id)
if(index !== -1)
{
 this.setState({ found: true })
}else{
 this.setState({ found: false })
}

Reference for findindex - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex

Upvotes: 1

Rick
Rick

Reputation: 1880

im not familiar with react, but normally a line like this: for (let x in products), will bring back a product for x, not an index. you are treating x like an index. is that part of the problem?

Upvotes: 1

Related Questions