data
data copied to clipboard
Support for non structured object
current my project has model that has non structured object property. it's like below data.
const userConfig1 = {
id: 1,
userId: 1,
config: {}
}
const userConfig2 = {
id: 1,
userId: 2,
config: { meta1: 1, meta2: 2 }
}
How about supporting unstructured object values by the Object
type? just like below code.
const db = factory({
userConfig: {
id: primaryKey(Number),
userId: Number
meta: Object
}
})
const userConfig1 = db.userConfig.create({ id: 1, userId: 1, meta: {} })
const userConfig2 = db.userConfig.create({ id: 2, userId: 2, meta: { meta1: 1, meta2: 2 } })
Hey, @strozw.
This is already supported, I believe. You can use the value getter function to return an empty object if that's the intended value:
factory({
userConfig: {
meta: () => ({}),
}
})
I'd expect that you should be able to create userConfig
entities with the following initial values:
db.userConfig.create({}) // "meta: {}"
db.userConfig.create({ meta: {} }) // "meta: {}"
db.userConfig.create({ meta: { meta1: 1 } }) // "meta: { meta1: 1 }"
You'd not have any of the userConfig.meta
properties described but that's the expected behavior when you say "unstructured object".
We also support optional properties via optional
. This allows you to describe the property but allow for null
as initial value. I don't think an empty object would be semantic to allow though, so it's unlikely the solution to use in your case.
@kettanaito
thank you for your quick reply.
I immediately tried the method introduced that is using () => ({})
, but the following problems occurred.
First, using () => ({})
as it is caused the following error in typescript.
So I had to cast it to any
like() => ({} as any)
.
Diagnostics:
1. Type '() => {}' is not assignable to type 'ModelDefinitionValue'.
Type '() => {}' is not assignable to type 'ModelValueTypeGetter'.
Type '{}' is not assignable to type 'ModelValueType'.
Type '{}' is missing the following properties from type 'PrimitiveValueType[]': length, pop, push, concat, and 28 more.
Next, by using () => ({})
, I was able to execute the following model creation code without error, but the actual value of userConfig.meta
is{{ It wasn't meta1: 1}
, but was the default{}
. and I also got the same result for updating the model.
const userConfig = db.userConfig.create({meta: {meta1: 1}})
You can see the above problem in the following playground. https://codesandbox.io/s/modest-fire-bobvlh?file=/src/index.ts
This is almost the same error that I get when I try to use getter function to describe nested array field https://github.com/mswjs/data/issues/162
I've ended up creating extra dependent object to work around this in the past. Would love to see a proper solution.
@kettanaito how can we create dynamic object of objects for which the key and value are created based on the mocks.
For example:
export default {
id: primaryKey(faker.datatype.number),
name: String
cars: Object // Not sure what to declared type as right now nothing works
};
//User mocks:
{
cars: {
hyundai: {
color: red
}
}
}
@vignesh-kira, there are two ways currently:
Nested object
factory({
car: {
id: primaryKey(String),
manufacturer: {
name: String
address: {
street: String
houseNumber: String
}
}
}
})
With plain nested objects, the car.manufacturer
is a literal object on the car
entity and does not exist as a separate entity to be queried.
Use a relationship
factory({
car: {
id: primaryKey(String),
manufacturer: oneOf('company')
},
company: {
id: primaryKey(String),
name: String,
address: {
street: String,
houseNumber: String
}
}
})
With the "car" - "company" relationship, both "car" and "company" (car.manufacturer
) are entities that can be queried separately or conjointly.
Update
I'm currently working on an internal rewrite of how models are parsed in the library. It heavily affects this feature in particular, as I'm unifying how nested model definitions can work.
Any progress on this @kettanaito ?
@tarjei, the best way to track the progress on this is through the Releases. When I'm done, it will be a new release.
Hi, just wanted to mention that I am looking forward this 'non-structured' object creation too. I have exactly the same issue as @strozw:
'Next, by using () => ({}), I was able to execute the following model creation code without error, but the actual value of userConfig.meta is{{ It wasn't meta1: 1}, but was the default{}. and I also got the same result for updating the model.'
Hope there is a fix of this soon. Also it would be great if it is possible to add it as nullable(Object)
We got bitten by this ourselves just now. We have an unstructured property args
that default to an empty {}
but could contain anything really. Our first attempt was to just define it as such:
const db = factory({
model: {
id: primaryKey(Number),
name: String,
args: () => ({}),
}
});
While this doesn't error, it also doesn't work as args
always remain an empty object when creating new instances of model
.
I'd love to use this library to mock data, but this feature is blocking me.
Let me know if this is already possible. I played around with it for a while and couldn't get the desired result.
I have a model with a field that has a nested, recursive structure, like:
type LeafNode = {
// some fields
}
type Expression = {
operator: string;
expressions: (Expression | LeafNode)[ ];
}
const foo = {
expression: {
operator: '+',
expressions: [
// items are a mix of Expression or LeafNode
]
}
}
But I don't think I can specify that the items in the expressions
array are of type Expression
or LeafNode
.
I just contributed to the bounty on this issue.
Each contribution to this bounty has an expiry time and will be auto-refunded to the contributor if the issue is not solved before then.
To make this a public bounty or have a reward split, the maintainer (@kettanaito) can reply to this comment.