1
votes

Comment définir selectId pour l'adaptateur d'entité lorsque l'ID pertinent est défini sur le backend?

Je distribue l'action / réducteur upsert sur mon magasin pour ajouter un nouvel enregistrement à l'état et il y a un effet qui appellera le backend et ajoutera l'enregistrement / le document à mon instance mongodb.

Étant donné que le seul identifiant raisonnable pour ce modèle particulier est défini par ma logique backend au moment de la création du document, comment dois-je définir selectId dans l'implémentation de mon entité dans mon front-end?

Pour le moment un élément est ajouté à l'état avec id: undefined et j'obtiens l'avertissement:

entity.js: 76 @ ngrx / entity: L'entité passée à selectId l'implémentation a renvoyé undefined. Vous devriez probablement fournir votre propre implémentation de selectId .

Mon adaptateur est défini comme:

@Effect()
  UpsertPublishedData$ = this.actions$.pipe(
    ofType<UpsertPublishedData>(PublishedDataActionTypes.UpsertPublishedData),
    switchMap(action => this.publishedDataApi.create(action.payload.publishedData)
    .pipe(mergeMap((data: PublishedData) => [ new UpsertPublishedData({ publishedData: data }),
      this.publishedDataApi.register(data[0].doi)]),
    catchError(err => of(new FailedPublishedDataAction(err)))))
  );

et l'effet pertinent est:

export const adapter: EntityAdapter<PublishedData> = createEntityAdapter<
  PublishedData
>({ selectId: (publishedData: PublishedData) => publishedData.doi });

publishedData.doi est le champ incriminé que je dois utiliser pour référencer l'entité.


0 commentaires

3 Réponses :


1
votes

Dans ce cas, je considérerai 2 options:

  • Option 1: mettre en œuvre une création pessimiste (pour rester simple)

Lorsqu'un nouvel enregistrement est créé par l'utilisateur, une action par exemple AddRecord appelle une requête POST à l'API backend. La réponse réussie émet une nouvelle action AddRecordSuccess qui ajoute le nouvel enregistrement créé (avec id envoyé par backend) dans le magasin avec @ ngrx / entity .

Pendant le processus de création (demande au backend), un indicateur de chargeur doit être affiché pour avertir l'utilisateur.

  • Option 2: mettre en œuvre une création optimiste (pour une meilleure UX)

Si une mise à jour optimiste est vraiment un besoin ou un objectif à atteindre, un id temporaire ou permanent doit être généré par l'application frontale:

  • id temporaire est utilisé à l'intérieur du magasin pour gérer les entités à synchroniser. Lorsque les entités sont créées par le backend, l ' id doit être mis à jour ou complété par un id backend permanent.

  • id permanent pourrait être généré par le front-end (UUID par exemple), et envoyé à être utilisé par le backend.

Dans tous les cas, @ ngrx / entity a besoin d'un identifiant ( numéro ou string ) pour identifier et gérer les entités en magasin.

/ p>

J'espère que cela aide.


4 commentaires

Aucune de ces options ne répond à la question. Ils reprennent simplement la question avec moins de détails.


désolé mais je ne comprends pas votre commentaire, j'ai vraiment essayé d'aider en donnant 2 options que je considérerai dans un tel cas. Vous avez besoin d'un identifiant, vous ne pouvez pas laisser indéfini. Peut-être devriez-vous donner plus d'explications ou plus de détails sur vos attentes.


L'option 1 pourrait résoudre le problème car l'entité est ajoutée après la réponse du backend (donc avec un identifiant). Mais je comprends que la création pessimiste ne pourrait pas être une option concernant vos spécifications UX.


Si vous aviez implémenté une entité, vous sauriez que la même action est utilisée pour déclencher des effets ainsi que pour modifier l'état afin qu'il n'y ait pas d'action "AddRecordSuccess"



1
votes

Pour l'instant, j'ai modifié le réducteur pour ne pas ajouter l'enregistrement à l'état lors du premier passage où le champ id (doi) n'est pas défini.

  case PublishedDataActionTypes.UpsertPublishedData: {
      return adapter.upsertOne(action.payload.publishedData, state);
    }

de ceci à l'origine:

case PublishedDataActionTypes.UpsertWaitPublishedData: {
  if (action.payload.publishedData && action.payload.publishedData.doi) {
    return adapter.upsertOne(action.payload.publishedData, state);
  }
  return state;
}

Cela garantit que l'état de l'enregistrement correspond à celui de la base de données. Cette approche est toujours conforme à une approche d'entité dans laquelle aucune action supplémentaire UpsertPublishedDataSuccess n'est requise.


1 commentaires

J'ai l'impression que l'adaptateur devrait gérer cela sans implémentation personnalisée



0
votes

Si vous parlez de ngrx / entity, spécifiez simplement une méthode selectId lors de la création de votre EntityAdapter. voir pour plus d'informations: createentityadapter

 dexport const adapter: EntityAdapter<Location > = createEntityAdapter<Location>({
  selectId: (location: Location) => location.locationid,
});


0 commentaires