Pular para o conteúdo principal

schema.Array

Cria um schema para normalizar um array de schemas. Se o valor de entrada for um Object em vez de um Array, o resultado normalizado será um Array com os valores do Object.

Nota: o mesmo comportamento pode ser definido com a sintaxe abreviada: [ mySchema ]

  • definition: obrigatório Um único schema que este array contém ou um mapeamento de valores de atributo para schema.
  • schemaAttribute: opcional (obrigatório se definition não for um único schema) O atributo em cada entity encontrada que define qual schema, de acordo com o mapeamento da definição, usar ao normalizar. Pode ser uma string ou uma função. Se for uma função, recebe os seguintes argumentos: _ value: O valor de entrada da entity. _ parent: O objeto pai do array de entrada. * key: A chave sob a qual o array de entrada aparece no objeto pai.
dica

Para coleções sem limite definido com chaves string, use schema.Values

dica

Torne-o mutável (novos itens podem ser adicionados com push/unshift) com Collections

Métodos de instância​

  • define(definition): Quando usado, a definition informada será mesclada com a definição original passada ao construtor de Array. Este método costuma ser útil para criar referências circulares no schema.

Uso​

Para descrever um array simples de um único tipo de entity:

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▶

Atualizando várias entities​

Use um Array com Controller.set() para gravar várias entities em uma única atualização do store, sem um endpoint.

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

Tipos polimórficos​

Se os dados de entrada forem um array com mais de um tipo de entity, é necessário definir um mapeamento de schema.

observação

Se seus dados retornarem um objeto para o qual você não forneceu um mapeamento, o objeto original será retornado no resultado e nenhuma entity será criada.

string schemaAttribute​

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▶

function schemaAttribute​

Os valores de retorno devem corresponder a uma chave em definition. Aqui mostraremos o mesmo comportamento do caso 'string', exceto que acrescentaremos um '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▶