Saltar al contenido principal

Values

Al igual que Array, Values no tiene un tamaño acotado. La definición aquí describe los tipos de valores esperados, y las claves pueden ser cualquier string.

Describe un mapa cuyos valores siguen el schema dado.

  • definition: obligatorio Un único schema que contiene este array o un mapeo de schema a valores de atributo.
  • schemaAttribute: opcional (obligatorio si definition no es un único schema) El atributo de cada entidad encontrada que define qué schema, según el mapeo de la definición, se usará al normalizar. Puede ser un string o una función. Si se da una función, recibe 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 aparece el array de entrada en el objeto padre.
consejo

Hazlo mutable (se pueden asignar nuevos elementos) con Collections

Métodos de instancia​

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

Values recibe su nombre de Object.values(), ya que sus schemas se usan para el valor de un Object.

Uso​

Fixtures
GET /items
{"firstThing":{"id":1},"secondThing":{"id":2}}
▶ItemPage.tsx
import { Entity, RestEndpoint, Values } from '@data-client/rest';
import { useSuspense } from '@data-client/react';

export class Item extends Entity {
  id = 0;
}
export const getItems = new RestEndpoint({
  path: '/items',
  schema: new Values(Item),
});
function ItemPage() {
  const items = useSuspense(getItems);
  return <pre>{JSON.stringify(items, undefined, 2)}</pre>;
}
render(<ItemPage />);
Resultado
Store▶

Actualizar muchas entidades​

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

ctrl.set(getItems.schema, {
firstThing: { id: 1 },
secondThing: { id: 2 },
});

Tipos polimórficos​

Si tus datos de entrada son un objeto con valores de más de un tipo de entidad, pero su schema no se puede definir fácilmente a partir de la clave, puedes usar un mapeo de schemas, de forma muy similar a Union y schema.Array.

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, Values } 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 Values(
    {
      link: Link,
      post: Post,
    },
    'type',
  ),
});
▶FeedList
Resultado
Store▶

schemaAttribute de tipo función​

Los valores de retorno deben coincidir con una clave de la definition. Aquí mostraremos el mismo comportamiento que en el caso de 'string', salvo que añadiremos 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, Values } 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 Values(
    {
      links: Link,
      posts: Post,
    },
    (input: Link | Post, parent: unknown, key: string) => `${input.type}s`,
  ),
});
▶FeedList
Resultado
Store▶