Sequelize-typescript: Invalid scope called

Created on 7 Jun 2018  路  13Comments  路  Source: RobinBuschmann/sequelize-typescript

SequelizeScopeError: Invalid scope dto called.
    at Function.scope (C:\MacGregor\BackEnd\node_modules\sequelize\lib\model.js:1422:15)

I have this error message which happens sometimes for some entities although the specified scope exists. Example:

@Scopes({
    dto: {
        attributes: ['id', 'name', 'description', 'position', 'serialNumber', 'runningHours', 'isActive', 'criticality', 'equipmentTypeId'],
        include: [() => EquipmentType.scope("dto")]
    },
})
@Scopes({
    dto: {
        attributes: ['id', 'name', 'description']
    },
})
@Table({
    tableName: 'equipmentType'
})
export class EquipmentType extends BaseModel<EquipmentType> {

In 90% of the code something like this work, but in some places it doesn't for some reason. Anyone had this issue?

bug wontfix

Most helpful comment

I came to the conclusion that there is no way to solve this. It makes perfectly sense, that the order matters here. Since you can't add a scope which depends on another which isn't resolved at the time of adding the former scope. So I think the only solution is - as @tdiam already pointed out - to add the scope dynamically.

All 13 comments

Hey @Aleksaas, can you confirm, that this only happens for entities where you've defined an include like include: [() => EquipmentType.scope("dto")]? That's at least what I guess causing the issue 馃If so, this is definitely a bug

A can confirm this issue.

I have reproduced this issue and found a workaround solution.I suppose this is because how sequelize inits models from the folder. This can be fixed if EquipmentType is initialized before the calling model is. You can try changing fileName with prefix a like aequipmentType.ts. This will make sequalize to init EquipmentType model with scopes first.

I realized that it actually depends on the order of model includes in this._sequelize.addModels([ method, so when I moved model EquipmentType to be before the model that includes it, it worked. That's why it seemed like random behavior and worked for some models and for some not.

Yes. I am not sure how we can set order of models during init method. But renaming for now is a valid working work-around solution to this problem.

But you don't have to rename. I just did this: this._sequelize.addModels([ EquipmentType, Equipment ])
instead of this: this._sequelize.addModels([ Equipment, EquipmentType ])
and it worked. Equipment includes EquipmentType.

Yes. This also works. For me, i am providing directory path for all the models. Hence renaming works for me. modelPaths: "/models/*.model"

@Aleksaas @sahilchaddha Maybe I misunderstood something, but when using addModels it is important to add all models, which have relations between each other, at once(!). So if you have an association between User and UserAddress, you need to addModels([User, UserAddress])

@RobinBuschmann Yes, but if u do something like this in User model: include: [() => UserAddress.scope("dto")] it will throw an error if u define UserAddress after User like this: addModels([User, UserAddress]). But if u define like this addModels([UserAddress, User]) it will work. That was the problem in my case. The order was important. If it is default scope, order is not important, but if it is custom scope like in my example, it is.

@Aleksaas Thanks for clarifying that :)

Is there any workaround for cases where both models need to use a scope of the other?

Example:

// User.ts
@Scopes({
    someScope1: { ... },
    withAddress: {
        include: [{
            model: () => UserAddress.scope("someScope2"),
            as: "address"
        }]
    }
})
class User extends Model<User> { ... }

and

// UserAddress.ts
@Scopes({
    someScope2: { ... },
    withUsers: {
        include: [{
            model: () => User.scope("someScope1"),
            as: "user"
        }]
    }
})
class UserAddress extends Model<UserAddress> { ... }

No order in addModels can fix this kind of circularity and Sequelize will always fail with Invalid scope [...] called. Any help appreciated.

I solved this by adding the scopes dynamically where needed, as per sequelize#9864. I used the addScope, since the solution with functional scopes from sushantdhiman did not work.

UserAddress.addScope("withUsers", {
    withUsers: {
        include: [{
            model: () => User.scope("someScope1"),
            as: "user"
        }]
    }
})

I came to the conclusion that there is no way to solve this. It makes perfectly sense, that the order matters here. Since you can't add a scope which depends on another which isn't resolved at the time of adding the former scope. So I think the only solution is - as @tdiam already pointed out - to add the scope dynamically.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

YaroslavOsetrov picture YaroslavOsetrov  路  3Comments

fareshan picture fareshan  路  4Comments

fareshan picture fareshan  路  3Comments

oscarcalvo picture oscarcalvo  路  3Comments

lilling picture lilling  路  4Comments