[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[ ] Feature request
[x] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:
It seems that the "Class Support" section is missing from the lastest version documentation. There's no information about a change related to this in the CHANGELOG.
Are you dropping support for class entities or it's just missing from the documentation?
We are not dropping the support, but it's not recommended to use it. You can see the docs here.
Hi @NetanelBasal I have some questions about class support...
I know that akita does not recommend using classes and when I was reading the reasons on docs I started to wonder why, so it says:
We can鈥檛 store classes in the database. A typical example of this is when you need to save the store snapshot.
That's true. But when I use class, is akita saving to its store as a class or as a plain object? Does it have any conversion?
I'm asking because, if we could store data as plain object exporting it automatically when user add or update, it would have the same behaviour as if it was using only plain objects. And when user query for it, it can instantiate back to the class.
So for that we can have a base class that akita would know how to instantiate and serialize. eg:
export class AkitaModel<T> {
// maybe constructor is not a good idea, we could move it to a static method
// that way, user would be able to have his own constructor implementation with no big issues
constructor(obj: Partial<T>): void {
Object.assign(this, obj);
}
// it will return plain object
toObject(): Partial<T> {
return { ...this };
}
}
user.model.ts
export class User extends AkitaModel {
firstName: string;
lastName: string;
token: string;
get name() {
return `${this.firstName} ${this.lastName}`;
}
}
So when user adds or updates, akita would call toObject() to get plaing object and, then when user query data, akita would call new baseClass(data).
If a base class is not a good solution, maybe we can try decorators that attach these methods to the model. I believe that it would give great powers for akita users!
thanks!
That's true. But when I use class, is Akita saving to its store as a class or as a plain object? Does it have any conversion?
It stores it as a class.
We can't store classes in the database. A typical example of this is when you need to save the store snapshot.
You can use it. Before you update the store, you just need to turn it to an instance when you get it as plain objects from the server.
const entities = response.map(entity => new BaseClass(entity));
store.set(entities);
But what do you think about the solution I gave?
Because as I understand, it's easier to handle store with plain objects like it says here:
- There are various third-party tools (for example immer) that only work with plain objects.
So the idea is to make akita able to handle conversions for the user... on that example you gave, once you set the baseClass for the store:
import { User } from './user.model';
@Injectable({ providedIn: 'root' })
@StoreConfig({
name: 'Users',
baseClass: User
})
export class UserStore extends EntityStore<UserState> {
constructor() {
super();
}
}
it would handle class automatically, so user would be able to provide data directly in plain objects:
const entities = response; //.map(entity => new BaseClass(entity));
store.set(entities); // set plain objects
or instances:
const user = new User();
store.set(user); // set instance object
Anyway, akita would convert it to plain object to store and make it compatible with other tools and whatever, but then it would convert back to instance of User when someone query for it.
We need to test what is the performance cost we pay here.
You can count on me if need any help. I can try to implement something, but I need a while to learn how akita core works