schema.Invalidate
Describes entities to be marked as INVALID. This removes items from a collection, or forces suspense for endpoints where the entity is required.
Constructor:
entity
which entity to invalidate. The input is used to compute the pk() for lookup.
Usage
Fixtures
GET /users
[{"id":"123","name":"Jim"},{"id":"456","name":"Jane"},{"id":"555","name":"Phone"}]
DELETE /users/:id
▶api/User
import { Entity, RestEndpoint } from '@data-client/rest'; class User extends Entity { id = ''; name = ''; } export const getUsers = new RestEndpoint({ path: '/users', schema: new schema.Collection([User]), }); export const deleteUser = new RestEndpoint({ path: '/users/:id', method: 'DELETE', schema: new schema.Invalidate(User), });
▶UserPage
import { getUsers, deleteUser } from './api/User'; function UsersPage() { const users = useSuspense(getUsers); const ctrl = useController(); return ( <div> {users.map(user => ( <div key={user.pk()}> {user.name}{' '} <span style={{ cursor: 'pointer' }} onClick={() => ctrl.fetch(deleteUser, { id: user.id })} > ❌ </span> </div> ))} </div> ); } render(<UsersPage />);
🔴 Live Preview
Store▶
Batch Invalidation
Here we add another endpoint for deleting many entities at a time by wrapping
schema.Invalidate
in an array. Data Client
can then invalidate
every
entity from the response.
Post
Resource
import Post from './Post'; export const PostResource = resource({ schema: Post, path: '/posts/:id', }).extend('deleteMany', { path: '/posts', body: [] as string[], method: 'DELETE', schema: [new schema.Invalidate(Post)], });
▶Request
import { PostResource } from './Resource'; PostResource.deleteMany(['5', '13', '7']);
Request
DELETE /posts
Content-Type: application/json
Body: ["5","13","7"]
Response200
[
{
"id": "5"
},
{
"id": "13"
},
{
"id": "7"
}
]
Sometimes our backend returns nothing for 'DELETE'. In this
case, we can use process to build
a usable response from the argument body
.
Post
Resource
import Post from './Post'; export const PostResource = resource({ schema: Post, path: '/posts/:id', }).extend('deleteMany', { path: '/posts', body: [] as string[], method: 'DELETE', schema: [new schema.Invalidate(Post)], process(value, body) { // use the body payload to inform which entities to delete return body.map(id => ({ id })); } });
▶Request
import { PostResource } from './Resource'; PostResource.deleteMany(['5', '13', '7']);
Request
DELETE /posts
Content-Type: application/json
Body: ["5","13","7"]
Response204
NO CONTENT
Impact on useSuspense()
When entities are invalidated in a result currently being presented in React, useSuspense() will consider them invalid
- For optional Entities, they are simply removed
- For required Entities, this invalidates the entire response re-triggering suspense.