Closed bestickley closed 2 years ago
Without more of the code its hard to truly say, but I am happy to offer some ideas to look into. I have noticed in some situations that the order that the imports are in can matter. Whether caused by this or not, are you sure that App actually exists at this point?
If you have created your appUser model in the constructor of the App for example, you can end up relying on a reference to an object that is still being constructed, and therefore still undefined.
Keen to know if you find the solution.
@Scotley, thank you for your response. I reached the conclusion that it was a circular dependency and have switched back to annotating the normal Vuex ORM classes with types as I don't have the extra time right now. I'll try and revisit this in the future.
To answer your question, I'm not sure if App actually exists at this point. I guess that's what I need to figure out.
I'm facing the same problem. As well on the BelongsTo method.
Cannot read property 'localKey' of undefined at Function.Model.belongsTo
Edit: @Scotley everything else is working perfectly. Only when I try to add a BelongsTo relation via the decorator it will be undefined. When I do the belongsTo relation via the fields method it is working.
More information, the given model is directly undefined within the BelongsTo
decorator. I think it is a problem with the imports as well. I'll be using the non typescript variant for now.
Odd, there must be a quirk with the BelongsTo decorator. I don't have a current project using the decorators so cannot test unfortunately, when I was using this I didn't run into any issues though which is strange. I will reopen this as there is obviously an issue. I suspect it is to do with the order that objects are being created, something that the decorators won't currently handle as they are just simplistic wrappers.
After too much research and time (Even i unit tested 100% the package), I come to conclusion that, this behavior is related to circular references and due to execution order of the models.
You will come across on this behavior every time you using inverse relationships
unfortunately :(
You can run this code with node
to see the results node filename.js
var User = function (profile) {
console.log('-> Profile');
console.log(typeof profile);
};
User(Profile); // "<- Profile is undefined in this point";
// The same goes with the decorators
var Profile = function (user) {
console.log('-> User');
console.log(typeof user);
};
Profile(User); // "ALL GOOD";
For example, if you using the hasOne
and belongsTo
relationships together then you will come across of this behavior (like the above example)
read comments.
// Let's say the order of the Models is like this.. first `Profile` and second `User` @OrmModel('profiles') export class Profile extends Model { @AttrField() id!: string;
@AttrField() user_id!: number;
@AttrField() age!: number;
@AttrField() sex!: string;
// Here we need the User model.
// *** but the problem is that we using 'User' class here before its declaration.
@BelongsToField(User, 'user_id')
user!: User;
}
@OrmModel('users') export class User extends Model { @AttrField() id!: string;
@AttrField() name!: string;
@HasOneField(Profile, 'user_id')
profile!: Profile;
}
I will try to find a solution or better implementation for the relationship decorators, but unfortunately this is a normal behavior.
Any help is welcome
MikroORM deals with it using expressions () => Model
MikroORM deals with it using expressions
() => Model
This is also how vuex-orm-next
is now handling model references to avoid circular issues. 👍
As for now, you can use the string name of the model instead of the class itself, but this behavior can be be pretty much fixed by changing this:
/**
* Adds the property as a 'Belongs To' relationship field
* @param parent The class of the parent model
* @param foreignKey The foreign key of this model
* @param ownerKey The key on the parent model
*/
export function BelongsToField(parent: typeof Model | string, foreignKey: string, ownerKey?: string) {
return Field(Model.belongsTo(parent, foreignKey, ownerKey));
}
to this:
export function BelongsToField(parent: string | () => typeof Model, foreignKey: string, ownerKey?: string) {
return Field(Model.belongsTo(
typeof parent === 'string' ? parent : parent(),
foreignKey,
ownerKey
));
}
I want to implement something like this, where my model A should have a field/property of type model B(ignores model A inside it) and model B should have field/property of type model A(but ignores model B property inside it), but I get the error that my model B has undefined property of model B itself. Please how do I avoid this circular dependency issue? I'm using vuex-orm-decorators library @TiBianMod
An example of what I'm trying:
Users.ts
import { Model } from "@vuex-orm/core"; import { AttrField, BelongsToManyField, OrmModel, PrimaryKey, } from "vuex-orm-decorators"; import { Roles } from "./roles"; import { RoleUser } from "./roleUser";
@OrmModel("Users") export class Users extends Model {
@AttrField(null) id: number;
@AttrField("") name: string;
@BelongsToManyField(Roles, RoleUser, "user_ids", "role_ids") roles: Roles[]; } export default Users
> Roles.ts
import { Model } from "@vuex-orm/core"; import { AttrField, BelongsToManyField, OrmModel, PrimaryKey, } from "vuex-orm-decorators"; import { Users } from "./users"; import { RoleUser } from "./roleUser";
@OrmModel("Roles") export class Roles extends Model {
@AttrField(null) id: number;
@AttrField("") name: string;
@BelongsToManyField(Users, RoleUser, "role_ids", "user_ids") users: Users[]; } export default Roles
> RoleUser.ts
import { Model } from "@vuex-orm/core"; import { AttrField, OrmModel, PrimaryKey, } from "vuex-orm-decorators";
@OrmModel("RoleUser") export class RoleUser extends Model {
@PrimaryKey() static primaryKey = ["role_ids", "user_ids"]
@AttrField(null) id: number;
@AttrField(new Array
@AttrField(new Array
} export default RoleUser
> User.vue
const items = User.query().with('roles').get()
> Roles.vue
const items = Roles.query().with('users').get()
> error
` Cannot read properties of undefined`
I recently switched to using vuex-orm-decorators from the normal way. Now, I'm getting a
Cannot read property 'localKey' of undefined
. Any ideas? I debugged the setup and thought this screenshot below might be helpful. It shows some of the classes not being imported correctly. This might not be a vuex-orm-decorators problem but do you have any suggestions for why this might be happening?Stack Trace:
appUser.ts
app.ts