Closed taylor009 closed 3 years ago
Thanks for submitting this issue. Could you include the code you used for creating the Neogma instance, the Jobs model and the folder structure?
It may be possible that you're importing this file before creating the Neogma instance.
This results in the error you reported:
import { JobsController } from "./src/controllers/Jobs";
export const neogma = new Neogma(
{
url: "bolt://localhost:7687",
username: "neo4j",
password: "password",
},
{
logger: console.log,
encrypted: false,
}
);
while this doesn't:
export const neogma = new Neogma(
{
url: "bolt://localhost:7687",
username: "neo4j",
password: "password",
},
{
logger: console.log,
encrypted: false,
}
);
import { JobsController } from "./src/controllers/Jobs";
that's why I recommend creating the Neogma instance as soon as you've run dotenv.config()
, before importing anything else!
Thanks, @themetalfleece that worked for me.
Added documentation here: https://themetalfleece.github.io/neogma-docs/docs/Models/Defining-a-Model#importing-neogma
@themetalfleece first of all, thank you and congrats for the library - it helps a lot.
I'm having an issue while integrating with Nest.js. I'm trying to decouple everything to keep my app "testable" but it is causing Cannot read property 'queryRunner' of undefined
error by the time the code bootstrap.
I tried to create the connection early, during the app bootstrap but it didn't work either - the dependency injection doesn't even have a chance to forcefully inject the connection via a module's custom provider.
What would be your suggestion for scenarios where we rely on DI to create/manage the class instances and DB connections as well?
Our scenario also requires to connect to different Neo4j instances which means different connection strings are managed dynamically (via service logic) to determine which connection string the DI needs to inject in the constructor and then to create a Neo4j connection. How can we accomplish something like that?
I will leave some snippets of the code for your reference:
app.module.ts
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
NeogmaModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService): Neo4jConfig => ({
scheme: configService.get('NEO4J_SCHEME') || 'bolt+s',
host: configService.get('NEO4J_HOST') || 'localhost',
port: configService.get('NEO4J_PORT') || '7687',
username: configService.get('NEO4J_USERNAME') || 'neo4j',
password: configService.get('NEO4J_PASSWORD') || 'neo4j',
database: configService.get('NEO4J_DATABASE') || 'default',
})
}),
AutomapperModule.withMapper(),
CommonModule,
]
})
export class ApplicationModule { }
neogma.service.ts
import { Driver, int } from 'neo4j-driver'
import { Injectable, Inject, OnApplicationShutdown, Logger } from '@nestjs/common';
import { NEOGMA_CONFIG, NEOGMA_DRIVER } from './neo4j.constants';
import { Neo4jConfig } from './neo4j-config.interface';
import { Neogma, QueryRunner } from 'neogma';
import { LoggerService } from '../common/provider/logger.service';
@Injectable()
export class NeogmaService implements OnApplicationShutdown {
private readonly logger = new Logger(NeogmaService.name);
public static neogmaConnection: Neogma;
neogma: Neogma;
runner: QueryRunner;
constructor(
@Inject(NEOGMA_CONFIG) private readonly config: Neo4jConfig,
@Inject(NEOGMA_DRIVER) private readonly driver: Driver
) {
this.logger.debug('Initialized');
this.runner = new QueryRunner({
driver: this.driver,
logger: LoggerService || console.log
});
}
public static async createNeogmaConnection(config: Neo4jConfig) {
return new Neogma({
url: `${config.scheme}://${config.host}:${config.port}` || 'bolt://192.168.33.10:7687',
username: config.username || 'neo4j',
password: config.password || 'Test1*'
},
{
logger: console.log,
encrypted: false,
disableLosslessIntegers: true
})
}
getDriver(): Driver {
return this.driver;
}
getNeogma(): Neogma {
NeogmaService.neogmaConnection = this.neogma;
return this.neogma;
}
getConfig(): Neo4jConfig {
return this.config;
}
int(value: number) {
return int(value)
}
onApplicationShutdown() {
return this.driver.close()
}
}
neogma.module.ts
import { DynamicModule, Module, Provider } from '@nestjs/common';
import { NEOGMA_CONFIG, NEOGMA_DRIVER } from './neo4j.constants';
import { ConfigModule } from '@nestjs/config';
import { Neo4jTransactionInterceptor } from './neo4j-transaction.interceptor';
import { NeogmaService } from './neogma.service';
import { Neo4jConfig } from './neo4j-config.interface';
import { NeogmaConnection } from '../../neogma.config';
@Module({
exports: [
NeogmaConnection,
NeogmaService
]
})
export class NeogmaModule {
static forRoot(config: Neo4jConfig): DynamicModule {
return {
module: NeogmaModule,
global: true,
providers: [
{
provide: NEOGMA_CONFIG,
useValue: config,
},
{
provide: NEOGMA_DRIVER,
inject: [NEOGMA_CONFIG],
useFactory: async (factoryConfig: Neo4jConfig) => {
return NeogmaService.createNeogmaConnection(factoryConfig)
},
},
NeogmaService,
],
exports: [
NeogmaService,
Neo4jTransactionInterceptor,
]
}
}
static forRootAsync(configProvider): DynamicModule {
return {
module: NeogmaModule,
global: true,
imports: [ConfigModule],
providers: [
NeogmaService,
{
provide: NEOGMA_CONFIG,
...configProvider
} as Provider<any>,
{
provide: NEOGMA_DRIVER,
inject: [NEOGMA_CONFIG],
useFactory: async (config: Neo4jConfig) => NeogmaService.createNeogmaConnection(config),
},
],
exports: [
NeogmaService,
]
}
}
}
@jotamorais Hey Jonathas, thanks for your message and the code snippets. This is very interesting and I want to try Neogma with Nest.js and provide a guide and a module for it. This is gonna take a bit though, but I'll let you know as soon as I have news, or if I need any more info. Thanks!
@jotamorais Hey Jonathas, thanks for your message and the code snippets. This is very interesting and I want to try Neogma with Nest.js and provide a guide and a module for it. This is gonna take a bit though, but I'll let you know as soon as I have news, or if I need any more info. Thanks!
No worries. That would be much appreciated. Let me know if i can be of any help.
Here is my controller code to create a new Node:
`export default class JobsController {