Конвертировать все идентификаторы Mirage JS в целые числа - PullRequest
0 голосов
/ 17 апреля 2020

Mirage JS предоставляет все идентификаторы моделей в виде строк. Наш бэкэнд использует целые числа, которые удобны для сортировки и так далее. После прочтения Mirage JS не поддерживает целочисленные идентификаторы из коробки. Из разговоров, которые я читал, лучшим решением было бы преобразовать идентификаторы в сериализаторе.

Output:

{
 id: "1",
 title: "Some title",
 otherValue: "Some other value"
}

Но я хочу:

Expected Output:

{
 id: 1,
 title: "Some title",
 otherValue: "Some other value"
}

Я действительно хочу преобразовать ВСЕ идентификаторы , Это будет включать в себя вложенные объекты и сериализованные идентификаторы.

Ответы [ 2 ]

0 голосов
/ 21 апреля 2020

Я думаю, , вы должны иметь возможность использовать собственный IdentityManager для этого. Вот пример REPL . (Примечание: REPL находится в стадии разработки + в настоящее время работает только на Chrome).

Вот код:

import { Server, Model } from "miragejs";

class IntegerIDManager {
  constructor() {
    this.ids = new Set();
    this.nextId = 1;
  }

  // Returns a new unused unique identifier.
  fetch() {
    let id = this.nextId++;
    this.ids.add(id);

    return id;
  }

  // Registers an identifier as used. Must throw if identifier is already used.
  set(id) {
    if (this.ids.has(id)) {
      throw new Error('ID ' + id + 'has already been used.');
    }

    this.ids.add(id);
  }

  // Resets all used identifiers to unused.
  reset() {
    this.ids.clear();
  }
}

export default new Server({
  identityManagers: {
    application: IntegerIDManager,
  },

  models: {
    user: Model,
  },

  seeds(server) {
    server.createList("user", 3);
  },

  routes() {
    this.resource("user");
  },
});

Когда я делаю запрос GET для / пользователей с этим сервером Я получаю целочисленные идентификаторы обратно.

0 голосов
/ 17 апреля 2020

Мое решение состоит в том, чтобы просмотреть данные и рекурсивно преобразовать все идентификаторы. Он работает довольно хорошо.

У меня есть ряд других требований, таких как удаление ключа data и встраивание или сериализация идентификаторов.

const ApplicationSerializer = Serializer.extend({
  root: true,

  serialize(resource, request) {
    // required to serializedIds
    // handle removing root key
    const json = Serializer.prototype.serialize.apply(this, arguments)
    const root = resource.models
      ? this.keyForCollection(resource.modelName)
      : this.keyForModel(resource.modelName)

    const keyedItem = json[root]

    // convert single string id to integer
    const idToInt = id => Number(id)

    // convert array of ids to integers
    const idsToInt = ids => ids.map(id => idToInt(id))

    // check if the data being passed is a collection or model
    const isCollection = data => Array.isArray(data)

    // check if data should be traversed
    const shouldTraverse = entry =>
      Array.isArray(entry) || entry instanceof Object

    // check if the entry is an id
    const isIdKey = key => key === 'id'

    // check for serialized Ids
    // don't be stupid and create an array of values with a key like `arachnIds`
    const isIdArray = (key, value) =>
      key.slice(key.length - 3, key.length) === 'Ids' && Array.isArray(value)

    // traverse the passed model and update Ids where required, keeping other entries as is
    const traverseModel = model =>
      Object.entries(model).reduce(
        (a, c) =>
          isIdKey(c[0])
            ? // convert id to int
              { ...a, [c[0]]: idToInt(c[1]) }
            : // convert id array to int
            isIdArray(c[0], c[1])
            ? { ...a, [c[0]]: idsToInt(c[1]) }
            : // traverse nested entries
            shouldTraverse(c[1])
            ? { ...a, [c[0]]: applyFuncToModels(c[1]) }
            : // keep regular entries
              { ...a, [c[0]]: c[1] },
        {}
      )

    // start traversal of data
    const applyFuncToModels = data =>
      isCollection(data)
        ? data.map(model => 
            // confirm we're working with a model, and not a value
            model instance of Object ? traverseModel(model) : model)
        : traverseModel(data)

    return applyFuncToModels(keyedItem)
  }
})
...