Closed iangregsondev closed 4 years ago
I should have mentioned (although its viewable in the stackblitz) - this is my source
const source = [
{
"id": "123",
"name": "CompanyA"
},
{
"id": "456",
"name": "CompanyB"
},
{
"id": "2424",
"name": "CompanyC"
},
{
"id": "111",
"name": "CompanyD"
}
]
and my destination type is Package
interface Item {
name: string
id: string
}
interface Package {
items: Item[],
}
I think where the problem is, of course I am not doing it correctly. Is the following
const myPackage: StrictSchema<Package, EmbeddedRecord[]> = {
items: a => morphism(item,a)
}
So I am passing the EmbeddedRecordp[] which is an array, so the conversion happens for each item in the array.
So for each item, a mapping is created for the whole array.
I can't really change the types / array that i am passing it BUT
if I do wrap the array inside of a plain object then I get the result. ie.
const tmp = {
elements: EmbeddedRecord[]
}
Hi,
Well i managed to do it but I am not sure if its correct, I have commented inline
const myPackage: Schema<Package, EmbeddedRecord[]> = { // Had to change StrictSchema to Schema
items: a => morphism(item,a)
}
const result2 = morphism(myPackage, [source]) // add to wrap source in []
Leaving it as strictSchema it gives types errors,
Could you explain a little more the difference between StrictSchema and Schema and when i would use one over the other?
The docs say that strictSchema means you have to map all values on the target but I am right ? which in my case is "items"
Hi @iangregsondev!
Instead of morphing towards the Package
type, I would create a morph from EmbeddedRecord
to Item
and then add it to a Package
object. Please see the example here: https://repl.it/@yrnd1/RequiredColorfulQuote
import { morphism, createSchema } from 'morphism';
interface EmbeddedRecord {
id: string
name: string
}
interface Item {
name: string
id: string
}
interface Package {
items: Item[]
}
const toItem = morphism(createSchema<Item, EmbeddedRecord>({
id: ({ id }) => id,
name: ({ name }) => name
}))
const source = [
{
"id": "123",
"name": "CompanyA"
},
{
"id": "456",
"name": "CompanyB"
},
{
"id": "2424",
"name": "CompanyC"
},
{
"id": "111",
"name": "CompanyD"
}
]
const pkg: Package = {
items: toItem(source)
}
console.log('pkg', JSON.stringify(pkg, null, 2))
// =>
/**
pkg {
"items": [
{
"id": "123",
"name": "CompanyA"
}, {
"id": "456",
"name": "CompanyB"
},
{
"id": "2424",
"name": "CompanyC"
},
{
"id": "111",
"name": "CompanyD"
}
]
}
**/
Is it what you're looking for ?
Thanks, yes this works, i was just hoping to be pass in an array and have it flattened.
The above example was a simple case and luckily my real example isn't too much of a difference.
But the package is being created manually rather than going through morphism.
Ok yes I see what you tried :) You could also achieve it by using the example above: https://repl.it/@yrnd1/RequiredColorfulQuote-1?lite=&classroom_template=&outputonly=&fileName=
I just find it a little less explicit
import { morphism, createSchema } from 'morphism';
interface EmbeddedRecord {
id: string
name: string
}
interface Item {
name: string
id: string
}
interface Package {
items: Item[]
}
const toItem = morphism(createSchema<Item, EmbeddedRecord>({
id: ({ id }) => id,
name: ({ name }) => name
}))
const toPackage = morphism(createSchema<Package,EmbeddedRecord[]>({
items: (source)=> toItem(source)
}))
const source = [
{
"id": "123",
"name": "CompanyA"
},
{
"id": "456",
"name": "CompanyB"
},
{
"id": "2424",
"name": "CompanyC"
},
{
"id": "111",
"name": "CompanyD"
}
]
const pkg= toPackage([source])
console.log('pkg', JSON.stringify(pkg[0], null, 2))
// =>
/**
pkg {
"items": [
{
"id": "123",
"name": "CompanyA"
},
{
"id": "456",
"name": "CompanyB"
},
{
"id": "2424",
"name": "CompanyC"
},
{
"id": "111",
"name": "CompanyD"
}
]
}
**/
Thank you! One last question, if I may :-)
I was using strict schema before but it was causing me issues with the above-mentioned solution. I had to switch to a normal schema.
It states that a strict schema ensures that you map all items on the destination. I did this but it did not work.
I presume the best way is to use a schema vs strict schema.
I still couldn't fully understand the difference after reading the documentation because according to the docs - that is not what was happening to me :-) Maybe I should try again.
Is it recommended just to use a schema?
Thanks again for all your help,
Here are the type definitions for Schema
and StrictSchema
:
https://github.com/nobrainr/morphism/blob/08434578d780d7f88ac676cc958b2190ff323659/src/types.ts#L35-L52
Notice the ?
in [destinationProperty in keyof Target]?
of the Schema
type. What it basically means is that when using a Schema
the fields are optional compared to a StrictSchema
where it's mandatory to define every field's mapping.
So it depends on what you want to achieve, but I would recommend if you want to ensure all the fields are mapped to use a StrictSchema
and the simplest way to do it is to use the helper createSchema<Target, Source>()
My pleasure :)
Thank you. I will close this now as i have everything working now.
Hi,
I wonder if you can help.
I have a Array of items but wish to return it flattened into items:, but it runs it multiple times.. I have placed a stackblitz at the end. I think I need to flatten but i didn't see an example.
The demo recreates what I am trying to do in production
I have created a stackblitz here that shows the issue
https://stackblitz.com/edit/morphism-single-source-to-complex-destination-1xms6b
Any ideas what I am doing wrong ?
If it helps, i am using Typescript but I doubt it makes a difference ?