mswjs / data

Data modeling and relation library for testing JavaScript applications.

Home Page:https://npm.im/@mswjs/data

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Fields with type `Array` cannot be an array of object

nvh95 opened this issue · comments

I have example code here:
https://github.com/nvh95/msw-example/blob/d144e5c98f165c15b8758e1157fa478952307d7f/src/mocks/browser.js#L4-L29
Given I have this schema:

const db = factory({
  user: {
    id: primaryKey(Number),
    email: String,
    additional_data: Array,
  },
});

Basically, I have a field additional_data which is an Array. If I create array of primitive type like string or number, it works fine.

db.user.create({
  ...
  additional_data: [1, 2, 3 ],
});

image

But if additional_data is an array of object, @mswjs/data seems cannot process it and returns an empty array

db.user.create({
  ...
  additional_data: [
    {
      key: "hobby",
      value: "code",
    },
    {
      key: "phone",
      value: "12345",
    },
  ],
});

Screenshot 2021-11-19 at 15 50 10

I have code to reproduce this issue in https://github.com/nvh95/msw-example/blob/msw-example-2021.11.19

git clone git@github.com:nvh95/msw-example.git
git checkout msw-example-2021.11.19
npm i
npm start

@kettanaito Can you take a look? Is this an issue or I misuse additional_data: Array (I refer to #113). (definitely I don't want to use manyOf here). Thank you very much.

@kettanaito I want to second this, I consider this a valid use.

The change was introduced in here: https://github.com/mswjs/data/pull/143/files#diff-64401d98a99c109c65a62a9cc791a32f21dddb5d08bce553aaa559b6aa0e382dL67-L74
And:

(Array.isArray(value) && value.every(isPrimitiveValueType))

Previously, the check was just that we got an array, and the contents of this array did not matter, but now create() will drop any array that contains non-primitive values and replace it with an empty array.

I think this is a regression.

Hey, @nvh95. Thank you for reporting this.

This does look like an issue, as Data should support primitive arrays on model definitions. I'll take a look at the pull request opened by @roertbb (huge thanks 🙌 ) and see if it's indeed a regression.

@kettanaito Thank you very much. I'm looking forward to see it fixed. In the mean time, I just want to share my work around:

  1. Change the model:
const db = factory({
  user: {
    id: primaryKey(Number),
    email: String,
-    additional_data: Array,
+    additional_data: () => [
+      {
+        key: "hobby",
+        value: "code",
+      },
+      {
+       key: "phone",
+        value: "12345",
+      },
+    ],
+  },
});
  1. Convert file contain the model from .ts to .js. Since TS does not allow me to define the model as above
    image
    Well, it looks not very good 🙈 but at least I feed some data for msw to respond.

The above workaround just gives a static value in the factory definition, you cannot create arrays with different values.
Here is a workaround that allows you to create different objects:

const db = factory({
  user: {
    id: primaryKey(Number),
    email: String,
    additional_data: Array,
  },
});

const user = {
  email: "example@example.com",
  additional_data: [
    {
      key: "hobby",
      value: "code",
    },
    {
      key: "phone",
      value: "12345",
    },
  ],  
}

// TEMPORARY WORKAROUND FOR #165
Object.defineProperty(user.additional_data, 'every', { value: () => true })

db.user.create(user)