-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Computed field for entity #68
Comments
Hi @VictorTBX , thanks for your suggestion. It seems your suggestion is related to the concept of computed properties, which is a feature that is not yet available in Herbs. Here are some benchmarks for this feature: Django: https://docs.djangoproject.com/en/4.1/topics/db/models/#model-methods On vanila JS, you can use getters and setters to achieve this: const person = {
name: 'Victor',
surname: 'Melias',
get fullname() {
return `${this.name} ${this.surname}`
}
} With that, my suggestion would be a new parameter in the entity definition, something like: const Person = entity('Person', {
id: field(Number),
name: field(String),
surname: field(String),
fullname: field(String, { value: (person) => `${person.name} ${person.surname}` })
}) A few things to consider:
Ex: const Person = entity('Person', {
...
fullname: field(String, { value: (person) => `${person.name} ${person.surname}` })
}) or const Order = entity('Order', {
...
total: field(Number, { value: (order) => order.items.reduce((total, item) => total + item.price, 0) })
})
const person = new Person({ name: 'Victor', surname: 'Melias' })
console.log(person.fullname) // should return 'Victor Melias'
person.name = 'John'
console.log(person.fullname) // should return 'John Melias'
const person = new Person({ name: 'Victor', surname: 'Melias' })
console.log(person.fullname) // should return 'Victor Melias'
person.fullname = 'John Melias' // should throw an error
const person = new Person({ name: 'Victor', surname: 'Melias' })
console.log(person.fullname) // should return 'Victor Melias'
console.log(person.toJSON()) // should return { id: 1, name: 'Victor', surname: 'Melias', fullname: 'Victor Melias' }
const Person = entity('Person', {
...
fullname: field(String, { value: (person) => `${person.name} ${person.surname}` }),
fullnameLength: field(Number, { value: (person) => person.fullname.length })
})
const Person = entity('Person', {
...
fullname: field(String, { value: async (person) => {
const { name, surname } = await fetchPerson(person.id)
return `${name} ${surname}`
} })
}) This is open to discussion, since this would change how to call a field (sync vs async). const person = new Person({ name: 'Victor', surname: 'Melias' })
console.log(await person.fullname) // should return 'Victor Melias' The problem here is that this also changes how to retrive value of a calculated field in glues, like herbs2rest and herbs2gql since they are expecting a sync value. So having a async value could be a next step, so I think it would be better to have a sync value first.
const Person = entity('Person', {
...
fullname: field(String, { value: function () {
return `${this.name} ${this.surname}`
} })
}) What else do you think we should consider? Again, thanks for your suggestion. Let's discuss it and see if we can implement it. I think it would be a great feature. |
const Person = entity('Person', {
id: field(Number),
name: field(String),
surname: field(String),
fullname: field(String, { value: function () {
if (person.name && person.surname)
return `${this.name} ${this.surname}`
} })
}) const person = new Person({ surname: 'Melias' })
console.log(person.fullname) // should return undefined person.name = 'Victor'
console.log(person.fullname) // should return 'Victor Melias' |
Great, thanks @dalssoft I think those are all things to be considered and will help to develop this feature. |
I started developing this feature, but I'm stucked with two problems:
How mandatory are these two concepts? The async is not developed as well, but I have successfully tested the other features, like toJson() |
Great! Thanks @VictorTBX . I recommend you to create a PR and we can discuss the issues you are facing there. I'm curios to understand why these features are a problem. I think it will be clear with code. |
…them when properties are set feature herbsjs#68
Describe the solution you'd like
Like in Object-oriented design, I'd like to read a field from an entity based on values of other fields. This would bring a concept of encapsulation to herbs' entities. This property, ideally, should not be able to be modified.
For example:
Additional context
In OOD languages this can be done by setting the properties with "private set", but there's no alternative in Herbs to do this without any kind of workaround
The text was updated successfully, but these errors were encountered: