Open LucasBadico opened 6 years ago
There's a 'Map'
type that will be unmarshalled into an ES6 Map
that gives you strongly typed member types. There's no equivalent that uses an object literal instead of a map, but one could be added.
Let's see.
My wanted schema
const phone = {
number: {
type: 'String'
},
areaCode: {
type: 'String'
}
}
const schema = {
phones: {
type: 'Collection',
memberType: embed(phone)
}
}
my entity
const entity = {
phones: {
'sjahdjasdh-kjsahdjksahd-klsjadj': { // unique id
number: '99999999',
areaCode: '00'
},
'sjahdjasdh-asdasdfsds-klsjadj': { // unique id
number: '99999999',
areaCode: '01'
}
}
}
This work with map?
’Collection’
wouldn’t be the right choice here — that’s used for arrays with untyped elements. There is a ’Hash’
type for objects with string keys and untyped values, but the values in phones
are strongly typed.
When unmarshalling the entity, you would get the follow if you used a ’Map’
type for phones
:
const entity = {
phones: new Map([
[‘<uuid1>’, {number: ‘...’, areaCode: ‘00’}],
[‘<uuid2>’, {number: ‘...’, areaCode: ‘01’}],
]),
};
I think what you’re describing would require a different scheme type (let’s call it ObjectMap
for now) that allows arbitrary keys that map to strongly typed values. I wouldn’t be opposed to adding that — the primary motivation for using ES6 Map
objects was to aid in type inference in a case like:
@table(‘foos’)
class Foo {
@attribute({memberType: embed(Widget)})
public widgets: Map<string, Widget> = new Map();
}
It’s more difficult to infer if you meant to use a map, an untyped hash, or a structured document if the map type is Object
, but that wouldn’t be an issue if you’re explicitly defining the schema.
Could we do this? I think that mappedCollection is a better name by the way.
I can help with this. I have been looking into the codebase.
Em qui, 12 de jul de 2018 às 12:47, Jonathan Eskew notifications@github.com escreveu:
When unmarshalling the entity, you would get the follow if you used a map:
const entity = { phones: new Map([ [‘
’, {number: ‘...’, areaCode: ‘00’}], [‘ ’, {number: ‘...’, areaCode: ‘01’}], ]), }; I think what you’re describing would require a different scheme type (let’s call it ObjectMap for now) that allows arbitrary keys that map to strongly typed values. I wouldn’t be opposed to adding that — the primary motivation for using ES6 Map objects was to aid in type inference in a case like:
@table(‘foos’)class Foo { @attribute({memberType: embed(Widget)}) public widgets: Map<string, Widget> = new Map(); }
It’s more difficult to infer if you meant to use a map, an untyped hash, or a structured document if the map type is Object, but that wouldn’t be an issue if you’re explicitly defining the schema.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/awslabs/dynamodb-data-mapper-js/issues/80#issuecomment-404558613, or mute the thread https://github.com/notifications/unsubscribe-auth/APwHGbCjYuSW9nhh7oQ3MzbARfiMcIaDks5uF299gaJpZM4VL6uU .
I was thinking, we can't call it just a Collection
with a memberType defined?
I would rather not use the term "collection" in the name, as it is typically used for containers of items without external keys (e.g., lists, sets, queues, stacks, etc., but not maps).
Other alternatives that commonly denote collections of key => value pairs include 'AssociativeArray'
, 'Table'
, or 'Dictionary'
... of those, I like 'Dictionary'
most.
Agreed on Dictionary
.
Already make a fork of the repo on my non-profit organization, then I we start make some tests, and rigth on start I open the pr and point to this issue.
[Edited]
Working on branch dictionary-feature
.
https://github.com/semeietech/dynamodb-data-mapper-js/tree/dictionary-feature
[Editing the proposal for the annotation] It will do, right?
class MyDomainClass {
@attribute({ memberType: embed(Phone) })
phones?: Dictionary<Phone>;
}
Or this Dictionary
key should be a typescript type? Is this a problem?
Also, have not beeing able to use annotations here on my project, so I build my domain with the Schema being injected on the class prototype.
So, in without annotations it will be something like this:
Object.defineProperties(MyDomainModel.prototype, {
[DynamoDbSchema]: {
value: {
phone: {
type: 'Dictionary',
memberType: embed(Phone)
},
},
},
});
I think you would want to declare the property as:
@attribute({ memberType: embed(Phone) })
phones?: {[key: string]: Phone;
TypeScript's metadata decorator will just tell you that phones
has a type of Object
, so you would need to rely on the presence of a memberType
property in the object passed to the annotation (as is done to distinguish List
s from Collection
s).
Get it. And in the class.prototype way, we could go for this:
Object.defineProperties(MyDomainModel.prototype, {
[DynamoDbSchema]: {
value: {
phone: {
type: 'Dictionary',
memberType: embed(Phone)
},
},
},
});
Am I right that this would be the only way to add an existing TypeScript type definition to a DynamoDB column of Map<string,any>
(JSON)?
Hey guys, needing some advice, @jeskew, maybe you know the answer...
I have
Accounts
, that have aphones
attribute, that is a phone map.I was looking ate the
collection
and I can't use a memberType for it, the mapper will do a auto-marshaller, rigth?There is a way to make a custom use the scheme? Or we extend the mapper to understand this use case?
I want to do this to have a unique identifier on phone.