Skip to main content

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.

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.

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.