14 votes

Mettre à jour l'objet ngrx à l'intérieur d'un tableau

J'ai un magasin ngrx avec un tableau d'objets. Ce que je cherche, c'est de mettre à jour (modifier) l'objet à l'intérieur du tableau en utilisant l'index du tableau. Mes données ngrx ressembleront à ceci :

    policies: {
        beneficiaries: {
            beneficiaries: [{
                    name: 'pqr'
                    age: 56
                },
                {
                    name: 'xyz'
                    age: 76
                }
            ]
        }
    }

Je dois mettre à jour le nom du bénéficiaire en fonction de l'index du tableau. J'ai donc implémenté la fonction reducer suivante :

    on(policiesActions.updateBeneficiaryPercentage, (state, action) => {
        return {
          ...state,
          beneficiaries: {
            ...state.beneficiaries,
            beneficiaries: {
              ...state.beneficiaries.beneficiaries,
              [action.index]: {
                ...state.beneficiaries.beneficiaries[action.index],
                name: action.value
              }
            }
          }
        };
      })

Le problème avec le code ci-dessus, c'est qu'après l'avoir exécuté, la structure de mon magasin change en :

policies: {
    beneficiaries: {
        beneficiaries: {
            0: {
                name: 'pqr'
                age: 1000
            },
            1: {
                name: 'xyz'
                age: 76
            }
        }
    }
}

Veuillez m'aider à corriger le code afin que je puisse mettre à jour la valeur sans altérer la structure du magasin.

18voto

timdeschryver Points 3762

Utilisez la méthode Array.map:

arr.map((value, index) => index === action.index ? {...value, name: action.value} : value) 

Ou utilisez simplement ngrx-etc, qui vous permet de muter votre état de manière mutable tout en restant immuable

mutableOn(onAction, (state, action) => {
  state.arr[action.index].name = action.name
  return state
})

10voto

Józef Podlecki Points 6888

Lors de la mise à jour d'un objet dans un tableau, je recréerais un tableau avec tous les objets exclus et j'ajouterais le dernier objet qui a besoin d'une valeur mise à jour.

const policies = {
  beneficiaries: {
    beneficiaries: [{
        name: 'pqr',
        age: 56
      },
      {
        name: 'xyz',
        age: 76
      }
    ]
  }
}

const updateObject = (state, action) => {

  if(!state.beneficiaries.beneficiaries[action.index]) {
    return state;
  }

  return {
    ...state,
    beneficiaries: {
      ...state.beneficiaries,
      beneficiaries: [
        ...state.beneficiaries.beneficiaries.slice(0, action.index),
        {
          ...state.beneficiaries.beneficiaries[action.index],
          name: action.value
        },
        ...state.beneficiaries.beneficiaries.slice(action.index + 1)
      ]
    }
  };
}

console.log(updateObject(policies, {index: 1, value: 'test'}))

--Modifier

Ajouté le snippet et modifié la logique pour ne pas changer l'ordre de la liste.

8voto

Darren Street Points 173

C'est une façon facile sans avoir recours à une plongée profonde dans l'objet state.

on(ProductActions.updateProductSuccess, (state, action): ProductState => {

  // définir une constante et parcourir l'état existant, insérer votre nouvel élément,
  // puis attribuer votre nouvel objet comme le nouvel état.

  const updatedProducts = state.products.map(
  product => action.product.id === product.id ? action.product : product);
  return {
    ...state,
    products: updatedProducts

   };
}),

Cela suppose que vous transmettez un objet produit complet dans votre action de succès.

4voto

Fabio Rizzello Points 41

Vous pouvez utiliser immer.js pour générer un nouvel état sans toucher à l'état précédent. Pas besoin de créer votre propre solution, plus recréer l'objet en clonant l'ancien manuellement est susceptible aux erreurs.

import produce from "immer"

on(policiesActions.updateBeneficiaryPercentage, (state, action) => {
  return produce(state, draftState => {
    draftState.policies.beneficiaries.beneficiaries[action.index].name = action.value
  })
})

Si vous voulez le faire de manière fonctionnelle, vous pouvez essayer les lentilles exemple utilisant ramda

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X