Saltar al contenido principal

schema.Array

Crea un schema para normalizar un array de schemas. Si el valor de entrada es un Object en lugar de un Array, el resultado normalizado será un Array con los valores del Object.

Nota: el mismo comportamiento se puede definir con la sintaxis abreviada: [ mySchema ]

  • definition: obligatorio Un schema singular que este array contiene o un mapeo de valores de atributo a schema.
  • schemaAttribute: opcional (obligatorio si definition no es un schema singular) El atributo de cada entidad encontrada que define qué schema, según el mapeo de definition, se usa al normalizar. Puede ser un string o una función. Si se le da una función, acepta los siguientes argumentos: _ value: El valor de entrada de la entidad. _ parent: El objeto padre del array de entrada. * key: La clave con la que el array de entrada aparece en el objeto padre.
consejo

Para colecciones sin límite con claves string, usa schema.Values

consejo

Hazlo mutable (se pueden agregar nuevos elementos con push/unshift) con Collections

Métodos de instancia​

  • define(definition): Cuando se usa, la definition que se pasa se fusionará con la definición original pasada al constructor de Array. Este método suele ser útil para crear referencias circulares en el schema.

Uso​

Para describir un array simple de un único tipo de entidad:

Fixtures
GET /users
[{"id":"123","name":"Jim"},{"id":"456","name":"Jane"}]
▶Users.tsx
import { Entity, RestEndpoint, schema } from '@data-client/rest';
import { useSuspense } from '@data-client/react';

export class User extends Entity {
  id = '';
  name = '';
}
export const getUsers = new RestEndpoint({
  path: '/users',
  schema: new schema.Array(User),
});
function UsersPage() {
  const users = useSuspense(getUsers);
  return (
    <div>
      {users.map(user => (
        <div key={user.pk()}>{user.name}</div>
      ))}
    </div>
  );
}
render(<UsersPage />);
Resultado
Store▶

Actualizar muchas entidades​

Usa un Array con Controller.set() para escribir muchas entidades en una sola actualización del store, sin un endpoint.

ctrl.set(
[User],
[
{ id: '123', name: 'Jim' },
{ id: '456', name: 'Jane' },
],
);

Tipos polimórficos​

Si tus datos de entrada son un array con más de un tipo de entidad, es necesario definir un mapeo de schemas.

nota

Si tus datos devuelven un objeto para el que no proporcionaste un mapeo, el objeto original se devolverá en el resultado y no se creará una entidad.

schemaAttribute de tipo string​

Fixtures
GET /feed
[{"id":1,"type":"link","url":"https://ntucker.true.io","title":"Nate site"},{"id":10,"type":"post","content":"good day!"}]
▶api/Feed
import { Entity, RestEndpoint, schema } from '@data-client/rest';

export abstract class FeedItem extends Entity {
  readonly id: number = 0;
  declare readonly type: 'link' | 'post';
}
export class Link extends FeedItem {
  readonly type = 'link' as const;
  readonly url: string = '';
  readonly title: string = '';
}
export class Post extends FeedItem {
  readonly type = 'post' as const;
  readonly content: string = '';
}
export const getFeed = new RestEndpoint({
  path: '/feed',
  schema: new schema.Array(
    {
      link: Link,
      post: Post,
    },
    'type',
  ),
});
▶FeedList
Resultado
Store▶

schemaAttribute de tipo función​

Los valores devueltos deben coincidir con una clave de definition. Aquí mostraremos el mismo comportamiento que en el caso 'string', excepto que agregaremos una 's'.

Fixtures
GET /feed
[{"id":1,"type":"link","url":"https://ntucker.true.io","title":"Nate site"},{"id":10,"type":"post","content":"good day!"}]
▶api/Feed
import { Entity, RestEndpoint, schema } from '@data-client/rest';

export abstract class FeedItem extends Entity {
  readonly id: number = 0;
  declare readonly type: 'link' | 'post';
}
export class Link extends FeedItem {
  readonly type = 'link' as const;
  readonly url: string = '';
  readonly title: string = '';
}
export class Post extends FeedItem {
  readonly type = 'post' as const;
  readonly content: string = '';
}
export const getFeed = new RestEndpoint({
  path: '/feed',
  schema: new schema.Array(
    {
      links: Link,
      posts: Post,
    },
    (input: Link | Post, parent: unknown, key: string) => `${input.type}s`,
  ),
});
▶FeedList
Resultado
Store▶