Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@ngrx/data optimisticUpdate does not work with custom selectId #2059

Closed
marcinmajkowski opened this issue Aug 11, 2019 · 14 comments · Fixed by #2060
Closed

@ngrx/data optimisticUpdate does not work with custom selectId #2059

marcinmajkowski opened this issue Aug 11, 2019 · 14 comments · Fixed by #2060
Assignees
Labels
Accepting PRs bug community watch Someone from the community is working this issue/PR Project: Data

Comments

@marcinmajkowski
Copy link
Contributor

marcinmajkowski commented Aug 11, 2019

Minimal reproduction of the bug/regression with instructions:

https://stackblitz.com/edit/angular-4lxmjk

Use @ngrx/data and define entity with following properties:

  • entityDispatcherOptions.optimisticUpdate set to true
  • selectId selecting property other than id (it is _id in my case).

Extend EntityCollectionServiceBase and call its update method (click "Update Foo name" button in Stackblitz application).

Update fails with following error:

Error: Hero EntityAction guard for "[Hero] @ngrx/data/save/update-one": payload has a missing or invalid entity key (id)

Expected behavior:

Optimistic update works same way as for entities with id named id.

Versions of NgRx, Angular, Node, affected browser(s) and operating system(s):

Any browser. @ngrx/[email protected].

Other information:

My quick guess is that this mustBeEntity call should be replaced with call to mustBeUpdate.

I would be willing to submit a PR to fix this issue

[X] Yes (Assistance is provided if you need help submitting a pull request)
[ ] No

@JiaLiPassion
Copy link
Contributor

@marcinmajkowski, yeah, I think you are right, should use mustBeUpdate.

@brandonroberts brandonroberts added bug Project: Data Accepting PRs community watch Someone from the community is working this issue/PR labels Aug 12, 2019
@brandonroberts
Copy link
Member

Thanks @marcinmajkowski, it's yours to fix if you want it.

@krisjobs
Copy link

krisjobs commented Aug 12, 2019

I'm heaving a similar issue with a call to mustBeUpdates()

Error: Hero EntityAction guard for "[Hero] @ngrx/data/entity-cache/save-entities": payload , item 1, has a missing or invalid entity key (id)

Even though the type checker yields no errors.

There is a stackblitz to reproduce (it's based on @marcinmajkowski's stackblitz)
https://stackblitz.com/edit/angular-4lxmjk-gbpd1g (EDITED)

@marcinmajkowski
Copy link
Contributor Author

@krisjobs you most likely shared wrong stackblitz since url is same as mine.

@krisjobs
Copy link

krisjobs commented Aug 12, 2019

Sorry -> https://stackblitz.com/edit/angular-4lxmjk-gbpd1g

I could also reproduce the error when the metadata's selectId is active.

I also find it strange, that entityCollectionService update() uses Partial< Hero >, while the changeSetItemFactory/entityCacheDispatcher update() uses Update< Hero >

@krisjobs
Copy link

krisjobs commented Aug 14, 2019

@marcinmajkowski may I have a look on your branch?

@marcinmajkowski
Copy link
Contributor Author

@krisjobs I am not sure which branch do you mean. This is where I have implemented a fix (one line changed): https://github.com/marcinmajkowski/platform/tree/2059 .

@marcinmajkowski
Copy link
Contributor Author

@krisjobs I was able to update multiple entities at once using following code:

    const entities = [
      { _id: 123, name: 'XXX' },
      { _id: 456, name: 'YYY' },
    ];

    this.heroService.updateManyInCache(entities);

There was no need for accessing dispatcher directly and no error occured.

I was also able to dispatch your changeSet by adding id property to changes object.

@JiaLiPassion
Copy link
Contributor

@marcinmajkowski , you can call updateManyInCache if the data is only updated in frontend and will not be send to backend, but in the normal case, we need to use dispatcher to dispatch action for update both backend and frontend.
And also add id property is not recommended in this case because the model doesn't have id property, to be consistent, app and ngrx/data should all use selectId function to get identifier.

@krisjobs
Copy link

krisjobs commented Aug 16, 2019

Please refer to my updated stackblitz @ https://stackblitz.com/edit/angular-4lxmjk-gbpd1g -> example.component.ts

@JiaLiPassion exactly, I would like to simultaneously make multiple CRUD saves on the back end side. I haven't tested the upsert operation (maybe I can use it as a workaround) but update does not work. Add/Delete do work.

@JiaLiPassion
Copy link
Contributor

@krisjobs, yeah, maybe upsert has the same issue.

@krisjobs
Copy link

@JiaLiPassion I've just tested it and it turns out dispatcher->upsert works properly, as it expects T[] and not Update[] as argument.

It's just dispatcher->update that isn't working

@JiaLiPassion
Copy link
Contributor

@krisjobs , thanks for the clarification!

@krisjobs
Copy link

I just found my problem was related to the fact, that update.changes should contain the id as well (even though it is already available as update.id.

as explained here:

Update is an object with a strict subset of the entity properties. It must include the properties that participate in the primary key (e.g., id). The update property values are the properties-to-update; unmentioned properties should retain their current values.

This is due to the fact update objects get flattened: updates.map(u => u.changes) in the DefaultDataService

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Accepting PRs bug community watch Someone from the community is working this issue/PR Project: Data
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants