Giter Site home page Giter Site logo

Comments (9)

EduVencovsky avatar EduVencovsky commented on September 2, 2024 8

Here is an example on how to get this error.

If you have a module of an entity Foo and also have a repository for Foo, you would have something like this

@Entity()
export class Foo {
  [EntityRepositoryType]?: FooRepository

  // other fields ...
}
@Repository(Foo)
export class FooRepository extends EntityRepository<Foo> {}

And in the module you would need to use MikroOrmModule.forFeature to register the entity and repository (using EntityRepositoryType in the entity), which would look something like:

@Module({
  imports: [MikroOrmModule.forFeature({ entities: [Foo] })],
  providers: [ /* foo services or providers */ ],
  controllers: [ /* foo controllers */ ]
})
export class FooModule {}

Later you think something like "I want to use this repository in other module, so I will export it" and you will do:

@Module({
  imports: [MikroOrmModule.forFeature({ entities: [Foo] })],
  providers: [ /* foo services or providers */, FooRepository], // repository added to providers
  exports: [FooRepository],
  controllers: [ /* foo controllers */ ]
})
export class FooModule {}

and in another module you would import FooModule and add to the constructor of your service FooRepository.

@Module({
  imports: [FooModule, /* bar module imports*/ ],
  providers: [ /* bar services or providers */ ], 
  controllers: [ /* bar controllers */ ]
})
export class BarModule {}
@Injectable()
export class BarService {
  constructor(public readonly fooRepository: FooRepository, /* other things injected*/) {}
}

And this is what will cause the error when trying to use the repositories in difference places.
I'm not sure if this is intentional or if it's a bug/something not possible to do (Maybe @B4nan could say something about it).

To solve this you need to remove the FooRepository from providers and exports from the FooModule and to use it in the BarModule you must use MikroOrmModule.forFeature to register Foo entity and it's repository.

@Module({
  imports: [ 
    MikroOrmModule.forFeature({
      entities: [FooEntity, BarEntity, /* other entities */],
    }),
  ],
  providers: [ /* bar services or providers */ ], 
  controllers: [ /* bar controllers */ ]
})
export class BarModule {}

This worked for me and hope this comment is good for people in the future.

from nestjs.

FelipeEmerim avatar FelipeEmerim commented on September 2, 2024 7

I had the same problem, in my case I was declaring my custom repository as a provider and also importing it in the module configuration. Removing the repository from the providers array solved it.

from nestjs.

sheyDev avatar sheyDev commented on September 2, 2024 2

You haven't added

@entity({ customRepository: () => UsersRepository })

in your entity declaration

from nestjs.

ChiefJacob avatar ChiefJacob commented on September 2, 2024 2

I just ran into this same issue, It would be helpful if the Documentation for MikroORM with NestJS went over this sort of thing.

from nestjs.

B4nan avatar B4nan commented on September 2, 2024 1

This is close to being unreadable, please learn how to format code properly :] Anyway, I was asking for executable repro, not for snippets of your code.

Looking at this, I can already see you have some entity definitions wrong (e.g. using mapToPk means the type is the PK type, not the entity). But that won't be the problem here.

You have something wrong in the Nest DI part, as apparently it won't pass the EM instance to the repository automatically.

Try looking at the existing example repositories.

from nestjs.

abelland avatar abelland commented on September 2, 2024 1

maybe what is missing here is the @InjectRepository(FooEntity) decorator before argument declaration

from nestjs.

B4nan avatar B4nan commented on September 2, 2024 1

I believe you should not export the repository like that, you should call the forFeature in the other module instead to have it available. Having it in the providers seems wrong too, the forFeature call is what registers the provider for giver repositories.

from nestjs.

B4nan avatar B4nan commented on September 2, 2024

Please provide executable reproduction. There is no way anybody can help based on just error message (not even full stack trace).

Will close this, issues should follow the issue template and need to be verifiable - will be happy to reopen if you can provide something I can actually try.

from nestjs.

Lishenga avatar Lishenga commented on September 2, 2024

Okay let me try to give you a proper picture of what am doing, am working on graphql api using nest js framework, am trying to login a person, so at the resolver level i have this code running

import { AuthService } from "../services/auth.service"; @Resolver(of => LoginUsers) export class AuthResolver { @Mutation(returns => AccessToken) signInLoginUser( @Args("signInCredentials") signInCredentialsDto: SignInCredentialsDto, ) { return this.authService.signIn(signInCredentialsDto); } }

the above code calls the authService, the authService executes this code
`
import { LoginUsersRepository } from 'src/users/repositories/loginusers.repository';

@Injectable()
export class AuthService {
constructor(
private loginUsersRepository: LoginUsersRepository,
){}
async signIn(signInCredentialsDto: SignInCredentialsDto ): Promise{
const user: LoginUsers = await this.loginUsersRepository.validateUserPassword(signInCredentialsDto)
if(!user){
throw new UnauthorizedException('Invalid Credentials');
}

    const roleName = await user.getUserRole()
    const { email, roleId } = user;

    const payload: JwtPayload = { email, roleId, roleName };
    const accesstoken = new AccessToken();
    accesstoken.accessToken = await this.jwtService.sign(payload)
    return accesstoken;
}

}
`

the authService then calls the loginUsersRepository which has this code running
`

import { LoginUsers } from "../entities/loginusers.entity";
import { EntityRepository } from "@mikro-orm/mongodb";
import { Repository } from "@mikro-orm/core";

@repository(LoginUsers)
export class LoginUsersRepository extends EntityRepository {

//....

async validateUserPassword(signInCredentialsDto: SignInCredentialsDto): Promise<LoginUsers | null> {
const { email, password } = signInCredentialsDto;
const user = await this.em.findOne(LoginUsers, { email: email })
console.log(user)
if(user && await user.validatePassword(password)){
return user;
}else{
return null;
}
}
}
so when this codeconst user = await this.em.findOne(LoginUsers, { email: email })in the loginUsersRepository, i get this error on the terminal
TypeError: Cannot read property 'getContext' of undefined
at LoginUsersRepository.get em [as em] (/Users/leon/Documents/code/node/nest/mikroORM/graphql-users-service-mikroORM/node_modules/@mikro-orm/mongodb/MongoEntityRepository.js:18:25)
at LoginUsersRepository.validateUserPassword (/Users/leon/Documents/code/node/nest/mikroORM/graphql-users-service-mikroORM/dist/users/repositories/loginusers.repository.js:86:33)
at AuthService.signIn (/Users/leon/Documents/code/node/nest/mikroORM/graphql-users-service-mikroORM/dist/auth/services/auth.service.js:73:54)
at AuthResolver.signInLoginUser (/Users/leon/Documents/code/node/nest/mikroORM/graphql-users-service-mikroORM/dist/auth/resolvers/auth.resolver.js:30:33)
at /Users/leon/Documents/code/node/nest/mikroORM/graphql-users-service-mikroORM/node_modules/@nestjs/core/helpers/external-context-creator.js:69:33
at processTicksAndRejections (node:internal/process/task_queues:93:5)
at async target (/Users/leon/Documents/code/node/nest/mikroORM/graphql-users-service-mikroORM/node_modules/@nestjs/core/helpers/external-context-creator.js:76:28)
at async /Users/leon/Documents/code/node/nest/mikroORM/graphql-users-service-mikroORM/node_modules/@nestjs/core/helpers/external-proxy.js:9:24

`
am wondering what have i done wrong?

The code for the LoginUsers entity is this
`
import { Field, ObjectType, ID } from "@nestjs/graphql";
import { Roles } from "./roles.entity";
import * as bcrypt from 'bcrypt';
import { SubRoles } from "./subrole.entity";
import { ObjectId } from "@mikro-orm/mongodb";
import { Entity, EntityRepositoryType, ManyToOne, PrimaryKey, Property } from "@mikro-orm/core";
import { LoginUsersRepository } from "../repositories/loginusers.repository";

@ObjectType()
@entity({ tableName: 'loginusers' })
export class LoginUsers {

[EntityRepositoryType]?: LoginUsersRepository;

@field(() => ID)
@PrimaryKey()
public _id!: ObjectId

@field()
@Property({ persist: true })
public email: string;

// @OnetoOne({ inversedBy: 'distributor', orphanRemoval: true, type: AuthenticationSubInstance })
// public subInstance!: AuthenticationSubInstance;

@field(type => SubRoles, { name: "subrole", nullable: true })
@manytoone({ persist: false, mapToPk: true, nullable: true })
public subRoleId?: SubRoles;

@field(type => Roles, { name: "role", nullable: true })
@manytoone({ persist: false, mapToPk: true, nullable: true })
public roleId?: Roles;

@field({ name: "roleName" })
public role: string

@field({ nullable: true })
@Property({ persist: true })
public firstName: string;

@field({ nullable: true })
@Property({ persist: true })
public lastName: string;

@Property({ persist: true })
public password: string;

@Property({ persist: true })
public salt: string;

@field({ nullable: true })
@Property({ onCreate: () => new Date(), persist: true })
public createdAt: Date;

@field({ nullable: true })
@Property({ onUpdate: () => new Date(), onCreate: () => new Date(), persist: true })
public updatedAt: Date;

async getUserRole(): Promise {
if (this.roleId != null) {
// console.log(this.roleId)
// const role = await getModelForClass(Roles).findOne({ _id: this.roleId }).exec()
return "Trial";
} else {
return null
}
}

async validatePassword(password: string): Promise {
console.log(this.password)
const hash = await bcrypt.hash(password, this.salt);
return hash === this.password;
}
}

`

and the configs for the MikroORM configs are these
`
import { MikroOrmModuleOptions } from '@mikro-orm/nestjs'
import * as config from 'config';
import { AuthenticationInstance } from 'src/users/entities/authentication-instance.entity';
import { AuthenticationSubInstance } from 'src/users/entities/authentication-subinstance.entity';
import { LoginUserRolePivotTable } from 'src/users/entities/loginuser-role.pivottable.entity';
import { LoginUserSubRolePivotTable } from 'src/users/entities/loginuser-subrole.pivottable.entity';
import { LoginUsers } from 'src/users/entities/loginusers.entity';
import { RolesPermissions } from 'src/users/entities/roles-permissions.pivottable.entity';
import { Roles } from 'src/users/entities/roles.entity';
import { SubRolePermissions } from 'src/users/entities/subrole-permissions.pivottable.entity';
import { SubRoles } from 'src/users/entities/subrole.entity';
import { Permissions } from 'src/users/entities/permissions.entity';

const { type, host, port, username, password, database, authSource } = config.get('db');

export const mikroOrmConfig: MikroOrmModuleOptions = {
type: 'mongo',
dbName: database,
debug: true,
entities: [
LoginUsers,
Roles,
AuthenticationInstance,
AuthenticationSubInstance,
LoginUserRolePivotTable,
LoginUserSubRolePivotTable,
Permissions,
RolesPermissions,
SubRolePermissions,
SubRoles,
],
baseDir: __dirname,
clientUrl: type + "://" + username + ":" + password + "@" + host + ":" + port + "/?" + authSource + "=admin&readPreference=primary&appname=MongoDB%20Compass&ssl=false",
}
`

What is it am i doing wrong? Please help

from nestjs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.