0

I was trying to add an state which suppose to have a array of indexes and each of these index must compare with state index and delete of store state, for example I have a product's state:

state.products = [
    {productName: "patric", withTax: "0.57", noTax: "2.30", tax: 25, quantity: 2}
    {productName: "parafuso", withTax: "55.50", noTax: "222.00", tax: 25, quantity: 2} //remove this
    {productName: "mamao", withTax: "0.57", noTax: "2.30", tax: 25, quantity: 5} // remove this
]

action.index = [
    {productName: "parafuso", withTax: "55.50", noTax: "222.00", tax: 25, quantity: 2} //remove this
    {productName: "mamao", withTax: "0.57", noTax: "2.30", tax: 25, quantity: 5} // remove this
]

    //this is not removing the selecteds items
    const products = state.products.filter((product, i) => {

        for(let i=0; i < action.index.length; i++){
            if(product.name !== action.index[i].name) return true
        }

        return false
    }) 
    return {
        ...state,
        products
    } 

3 Answers 3

1

I would take a similar but optimised approach.

First of all I would just extract the names of the products you want to remove since it makes no sense to run a for look for every item of the products you have in the state.

Second, having an indexOf instead of a for loop with equality operator === performs faster since the browser can optimise the execution.

Finally, try to improve readability.

// Given that this is your state
state.products [
  {productName: "patric", withTax: "0.57", noTax: "2.30", tax: 25, quantity: 2}
  {productName: "parafuso", withTax: "55.50", noTax: "222.00", tax: 25, quantity: 2} //remove this
  {productName: "mamao", withTax: "0.57", noTax: "2.30", tax: 25, quantity: 5} // remove this
]

// Given that this is the action you dispatch
action = {
  type: 'FILTER_PRODUCTS'
  index: [
    {productName: "parafuso", withTax: "55.50", noTax: "222.00", tax: 25, quantity: 2} //remove this
    {productName: "mamao", withTax: "0.57", noTax: "2.30", tax: 25, quantity: 5} // remove this
  ]
}

//Reducer code...
case 'FILTER_PRODUCTS': {

  // extract the names just once
  const namesToRemove = action.index.map( product => product.name )

  // filter the products
  const products = state.products.filter( product => namesToRemove.indexOf( product.name ) === -1 )

  return { ...state, products } 
}

EDIT

You can also replace the Array.indexOf with the newer Array.includes.

const products = state.products.filter( product => namesToRemove.indexOf( product.name ) === -1 )

becomes

const products = state.products.filter( product => ! namesToRemove.includes( product.name ) )
Sign up to request clarification or add additional context in comments.

1 Comment

I suggested to replace indexOf with includes since it is more clear
0

Use the .filter() function as it returns an immutable array of the array without the value you want to delete. I'm assuming that your asking about removing an element from state inside your reducer, your question kind of seems all over the place...

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

state.products [
  {name: pudim},
  {name: car}, //want to remove this
  {name: cloud} //want to remove this
]

//Reducer code...

case ProductActionType.SELECT_PRODUCT: { 
  const products = state.products.filter((product, index) => { 
    for(let i=0; i < action.productFromAction.length; i++){
        if(product.name === action.productFromAction[i].name) return false
    }
    return true
  }) 
  return { ...state, products } 
}

10 Comments

Actually the 'action.productFromAction.name' is also an array which have the objects rows to delete, but if I enter like this, I cannot read throught the array to check each name of object. ` case ProductActionType.SELECT_PRODUCT: { const indexedProduct = action.index.map(index => { return state.products[index] }) const products = state.products.filter((product, i) => { return product.name !== indexedProduct[i].name }) console.log(products) return { ...state } } ` Just to clarify this, i want to delete the 2 index in a row, is that possible?
You can't filter it simply by index, there has to be some kind of unique identifier for each element in your data store that maps to your array of data. If you just try to check by index, it won't always give you the correct value. So in this instance, I'm going to assume your name is a unique identifier. If it is, try this:
I updated my answer to include filtering out an array of elemnts. Let me know if that works for you.
No this isn't working as expected, it is removing all indexes.
Wow now It works, I needed also to block undefined return statement.
|
0

If you want to keep only the product with the index in the state, this can be done with the filter function.

like this

let state = {
  products: [{
      name: 'pudim'
    },
    {
      name: 'car'
    },
    {
      name: 'cloud'
    }
  ],
  index: [1,2] 
}

const withoutRemoved = state.products.filter((product, i) => state.index.indexOf(i) === -1 )

console.log( {
  ...state,
  products: withoutRemoved
})

mapalways returns an array with the same spaces even if they are `` undefined

4 Comments

Yeah I agree with you, but, I don't want to do this, what I want to is to delete not one, but multiple indexes at same time, for example 2 rows of a table is equals to 2 indexes of my Array, and I want to delete those 2 rows at the same time.
instead of using simple index use an array and filter the products which indexes ain't in the array
i just updated the example to work with an array of indexes to delete
I will use your logic.

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.