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

How to save a File in msw-data

akshymalvia opened this issue · comments

Here's how I've defined the model definition for file type, not using File or Blob constructors as they're throwing errors.

Model definition

import { uid } from "quasar";
import { primaryKey } from "@mswjs/data";

export default {
  id: primaryKey(uid),
  dateCreated: () => new Date(),
  dateUpdated: () => new Date(),
  content: Object,
};

The way I'm trying to create the model instance.

import { db } from "../database";

const createdFile = db.file.create({content: File});

I'm getting this as createdFile, empty object as content instead of the File.

{
  id: primaryKey(uid),
  dateCreated: () => new Date(),
  dateUpdated: () => new Date(),
  content: {}
}

I don't know what I'm doing wrong here.

Using @mswjs/data^0.10.2

Hey, @akshymalvia.

What error do you get when using the File instance in the model definition?

export default {
  id: primaryKey(uid),
  dateCreated: () => new Date(),
  dateUpdated: () => new Date(),
  content: () => new File([], 'default'),
};

Hi, @kettanaito thanks for the quick response.

This is the error that I'm getting

Screenshot 2022-11-24 at 16 35 54

Here's an example of using File as a model value:

import { factory, primaryKey } from "@mswjs/data";

const db = factory({
  file: {
    id: primaryKey(() => Math.random().toString(32).slice(2)),
    content: () => new File([], "")
  }
});

const file = db.file.create({
  content: new File(["hello"], "filename.txt")
});

console.log(file);

Note that this won't be compatible with TypeScript because File is not assignable to the model value type that the library expects:

data/src/glossary.ts

Lines 21 to 22 in efb1747

export type PrimitiveValueType = string | number | boolean | Date
export type ModelValueType = PrimitiveValueType | PrimitiveValueType[]

We seem to be explicit about the supported types. Maybe this is a room for improvement in the future.

Here's an example of using File as a model value:

import { factory, primaryKey } from "@mswjs/data";

const db = factory({
  file: {
    id: primaryKey(() => Math.random().toString(32).slice(2)),
    content: () => new File([], "")
  }
});

const file = db.file.create({
  content: new File(["hello"], "filename.txt")
});

console.log(file);

Note that this won't be compatible with TypeScript because File is not assignable to the model value type that the library expects:

data/src/glossary.ts

Lines 21 to 22 in efb1747

export type PrimitiveValueType = string | number | boolean | Date
export type ModelValueType = PrimitiveValueType | PrimitiveValueType[]

We seem to be explicit about the supported types. Maybe this is room for improvement in the future.

Hey @kettanaito, thanks for the Sandbox.

There's an issue with file creation, the created file does not have the contents of the file assigned to content key, instead, it has the contents of the initial model definition, I faced this issue locally and then checked out the Sandbox, and the behavior is the same.

Hey @kettanaito, thanks for the Sandbox.

There's an issue with file creation, the created file does not have the contents of the file assigned to content key, instead, it has the contents of the initial model definition, I faced this issue locally and then checked out the Sandbox, and the behavior is the same.

Why the created file doesn't have the assigned content?

Likely because we don't have support for custom classes as model value types, as I've said. I don't know at the moment what such support would imply, I haven't worked on Data in quite some time.

Because File is not a primitive value, so this check fails:

if (isModelValueType(initialValue)) {

export function isModelValueType(value: any): value is ModelValueType {

Then, createModel uses the property definition function to populate the value:

set(properties, propertyName, propertyDefinition())

And since that property definition is () => new File([], '') (the default value from the model definition), you always get that default value no matter which custom value you provide when creating a model.

Hi @kettanaito, thanks for the answer.

I want to work on adding support for File. Would you think it through, should it be supported or not?

I can also help implement persistence if you guide me through it, like how it should be implemented.