I am attempting to reuse a service (Inventory) in another service (Order) class like so
order.module.ts
import { InventoryModule } from '../inventory/inventory.module';
#Module({
imports: [TypeOrmModule.forFeature([OrderEntity]), InventoryModule],
controllers: [OrderController],
providers: [OrderService],
})
export class OrderModule {}
and then use InventoryService methods inside OrderService like so
#Injectable()
export class OrderService {
constructor(
#InjectRepository(OrderEntity) private orderRepository: Repository<OrderEntity>,
private inventoryService: InventoryService) {}
/**
* Add order item
* #param data Object
*/
async add(data: OrderDTO) {
const { inventory_item_id } = data
const inventoryItem = await this.inventoryService.getOne(inventory_item_id)
if (inventoryItem.quantity_available <= 0) {
throw new Error('Cannot add item to order, insufficient quantities!')
}
const orderItem = await this.orderRepository.create(data)
if (orderItem) {
const updatedInventoryItemQuantity = inventoryItem.quantity_available - 1
const updatedInventoryItem = await this.inventoryService.edit(inventory_item_id, {
quantity_available: updatedInventoryItemQuantity,
})
}
await this.orderRepository.save(orderItem)
return orderItem
}
but I get the following stack trace:
Require stack:
- /Users/jred/workspace/projects/my-proj/dist/order/order.service.js
- /Users/jred/workspace/projects/my-proj/dist/order/order.controller.js
- /Users/jred/workspace/projects/my-proj/dist/order/order.module.js
- /Users/jred/workspace/projects/my-proj/dist/app.module.js
- /Users/jred/workspace/projects/my-proj/dist/main.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:623:15)
at Function.Module._load (internal/modules/cjs/loader.js:527:27)
at Module.require (internal/modules/cjs/loader.js:681:19)
at require (internal/modules/cjs/helpers.js:16:16)
at Object.<anonymous> (/Users/jred/workspace/projects/my-proj/dist/order/order.service.js:19:29)
at Module._compile (internal/modules/cjs/loader.js:774:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:785:10)
at Module.load (internal/modules/cjs/loader.js:641:32)
at Function.Module._load (internal/modules/cjs/loader.js:556:12)
at Module.require (internal/modules/cjs/loader.js:681:19) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/Users/jred/workspace/projects/my-proj/dist/order/order.service.js',
'/Users/jred/workspace/projects/my-proj/dist/order/order.controller.js',
'/Users/jred/workspace/projects/my-proj/dist/order/order.module.js',
'/Users/jred/workspace/projects/my-proj/dist/app.module.js',
'/Users/jred/workspace/projects/my-proj/dist/main.js'
]
}
anyone experience this? what is the correct way to call an imported service in another module?
Check your app.module.ts.
Make sure you added InventoryModule in the imports array.
And also, make sure you are exporting InventoryService from InventoryModule.
// app.module.ts
#Module({
imports: [InventoryModule, ...othermodules],
exports: [],
providers: []
})
export class ApplicationModule {}
// inventory.module.ts
#Module({
imports: [...yourModules],
exports: [InventoryService],
providers: [InventoryService]
})
export class InventoryModule {}
the problem was within my Order.service.ts file with the auto import syntax
this import that included src
import { InventoryService } from 'src/inventory/inventory.service';
had to be changed to this
import { InventoryService } from '../inventory/inventory.service';
Related
I'm trying to implement query complexity for my nestjs v8 graphql queries, but I can't find a fully working example...
Following the docs (https://docs.nestjs.com/graphql/complexity) I created my ComplexityPlugin
import { GraphQLSchemaHost } from '#nestjs/graphql';
import { Plugin } from '#nestjs/apollo';
import {
ApolloServerPlugin,
BaseContext,
GraphQLRequestContext,
GraphQLRequestListener,
} from 'apollo-server-plugin-base';
import { GraphQLError } from 'graphql';
import {
fieldExtensionsEstimator,
getComplexity,
simpleEstimator,
} from 'graphql-query-complexity';
#Plugin()
export class ComplexityPlugin implements ApolloServerPlugin {
constructor(private gqlSchemaHost: GraphQLSchemaHost) {}
requestDidStart(
requestContext: GraphQLRequestContext<BaseContext>,
): void | GraphQLRequestListener<BaseContext> {
const maxComplexity = 20;
const { schema } = this.gqlSchemaHost;
return {
async didResolveOperation({ request, document }) {
const complexity = getComplexity({
schema,
operationName: request.operationName,
query: document,
variables: request.variables,
estimators: [
fieldExtensionsEstimator(),
simpleEstimator({ defaultComplexity: 1 }),
],
});
if (complexity > maxComplexity) {
throw new GraphQLError(
`Query is too complex: ${complexity}. Maximum allowed complexity: ${maxComplexity}`,
);
}
console.log('Query Complexity:', complexity);
},
};
}
}
then added in my module as a provider
and then in my app.module.ts -> imports ->
GraphQLModule.forRoot({
...
plugins: [new ComplexityPlugin()],
...
}),
but new ComplexityPlugin() expects a GraphQLSchemaHost object as parameter... now what?
If I don't add it as a plugin into GraphQLModule.forRoot, I get this error:
TypeError: Class extends value undefined is not a constructor or null
at Object.<anonymous> (/home/johnykes/code/my-service/node_modules/#nestjs/apollo/dist/services/plugins-explorer.service.js:6:48)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/home/johnykes/code/my-service/node_modules/#nestjs/apollo/dist/drivers/apollo-federation.driver.js:9:36)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/home/johnykes/code/my-service/node_modules/#nestjs/apollo/dist/drivers/index.js:4:22)
at Module._compile (node:internal/modules/cjs/loader:1105:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (/home/johnykes/code/my-service/node_modules/#nestjs/apollo/dist/index.js:5:22)
From the docs you could just add the ComplexityPlugin as a provider in the providers array.
My colleague just found the solution:
npm i package "graphql-query-complexity": "...,
create plugin
import { Plugin } from '#nestjs/graphql';
import {
ApolloServerPlugin,
GraphQLRequestListener,
GraphQLServiceContext,
} from 'apollo-server-plugin-base';
import { GraphQLError, GraphQLSchema } from 'graphql';
import {
fieldExtensionsEstimator,
getComplexity,
simpleEstimator,
} from 'graphql-query-complexity';
#Plugin()
export class ComplexityPlugin implements ApolloServerPlugin {
private schema: GraphQLSchema;
constructor() {}
async serverWillStart(service: GraphQLServiceContext) {
this.schema = service.schema;
}
async requestDidStart(): Promise<GraphQLRequestListener> {
const maxComplexity = 100;
const schema = this.schema;
return {
async didResolveOperation({ request, document }) {
const complexity = getComplexity({
schema,
operationName: request.operationName,
query: document,
variables: request.variables,
estimators: [
fieldExtensionsEstimator(),
simpleEstimator({ defaultComplexity: 1 }),
],
});
if (complexity > maxComplexity) {
throw new GraphQLError(
`Query is too complex: ${complexity}. Maximum allowed complexity: ${maxComplexity}`,
);
}
},
};
}
}
in app.module.ts, add:
import { ComplexityPlugin } from './modules/common/complexity.plugin';
...
GraphQLModule.forRoot({
...
plugins: [new ComplexityPlugin()],
formatError: (error: GraphQLError) => {
const graphQLFormattedError: GraphQLFormattedError = {
...error,
message:
error.extensions?.exception?.response?.message || error.message,
};
console.error(graphQLFormattedError);
return {
...graphQLFormattedError,
extensions: { ...graphQLFormattedError.extensions, exception: null },
};
},
}),
in your graphql input args, add:
import { IsOptional, Max } from 'class-validator';
...
#IsOptional()
#Max(100)
#Field(() => Int, { nullable: true, description: 'Paginate first' })
public first?: number = 10;
...
I get this error:
Nest can't resolve dependencies of the UserPreferencesService (?). Please make sure that the argument UserPreferencesSchemaModel at index [0] is available in the UserPreferencesModule context.
What can the error be? I understand that the problem happens in the user-preferences.service.ts file. as when I comment the following lines from the user-preferences.module.ts file all works fine.
controllers: [UserPreferencesController],
providers: [UserPreferencesService],
This is my user-preferences.service.ts file:
import { Injectable } from '#nestjs/common';
import { Model } from 'mongoose';
import { InjectModel } from '#nestjs/mongoose';
import { UserPreferencesInterface } from './interfaces/user-preferences.interface';
#Injectable()
export class UserPreferencesService {
constructor(
#InjectModel('UserPreferencesSchema')
private readonly UserPreferencesModel: Model<UserPreferencesInterface>,
) {}
public async postUserPreferences(newUserPreferences: any): Promise<any> {
const userPreferences = await new this.UserPreferencesModel(
newUserPreferences,
);
return userPreferences.save();
}
}
app.module.ts
import { Module } from '#nestjs/common';
import { UserPreferencesModule } from './user-preferences/user-preferences.module';
import { MongooseModule } from '#nestjs/mongoose';
#Module({
imports: [
UserPreferencesModule,
MongooseModule.forRoot(
'mongodb+srv://user:pass#db.hucjifz.mongodb.net/dbname?retryWrites=true&w=majority',
),
],
})
export class AppModule {}
user-preferences.module.ts
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { UserPreferencesSchema } from './schemas/user-preferences.schema';
import { UserPreferencesController } from './user-preferences.controller';
import { UserPreferencesService } from './user-preferences.service';
#Module({
imports: [
MongooseModule.forFeature([
{
name: 'UserPreferences',
schema: UserPreferencesSchema,
},
]),
],
controllers: [UserPreferencesController],
providers: [UserPreferencesService],
})
export class UserPreferencesModule {}
user-preferences.controller.ts
import {Body, Controller, Get, Post, Put } from '#nestjs/common';
import { UserPreferencesService } from './user-preferences.service';
import { UserPreferencesDto } from './dto/user-preferences.dto'
#Controller('user-preferences')
export class UserPreferencesController {
constructor(private userPreferencesService: UserPreferencesService) {}
#Get()
public getUserPreferences() {
return this.userPreferencesService.getUserPreferences();
}
#Post ()
public postUserPreferences(
#Body() userPreferences: UserPreferencesDto
) {
return this.userPreferencesService.postUserPreferences( userPreferences );
}
}
this is the complete error:
[Nest] 65481 - 06/07/2022, 6:00:04 AM ERROR [ExceptionHandler] Nest can't resolve dependencies of the UserPreferencesService (?). Please make sure that the argument UserPreferencesSchemaModel at index [0] is available in the UserPreferencesModule context.
Potential solutions:
- If UserPreferencesSchemaModel is a provider, is it part of the current UserPreferencesModule?
- If UserPreferencesSchemaModel is exported from a separate #Module, is that module imported within UserPreferencesModule?
#Module({
imports: [ /* the Module containing UserPreferencesSchemaModel */ ]
})
Error: Nest can't resolve dependencies of the UserPreferencesService (?). Please make sure that the argument UserPreferencesSchemaModel at index [0] is available in the UserPreferencesModule context.
Potential solutions:
- If UserPreferencesSchemaModel is a provider, is it part of the current UserPreferencesModule?
- If UserPreferencesSchemaModel is exported from a separate #Module, is that module imported within UserPreferencesModule?
#Module({
imports: [ /* the Module containing UserPreferencesSchemaModel */ ]
})
at Injector.lookupComponentInParentModules (/Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/injector.js:231:19)
at Injector.resolveComponentInstance (/Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/injector.js:184:33)
at resolveParam (/Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/injector.js:106:38)
at async Promise.all (index 0)
at Injector.resolveConstructorParams (/Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/injector.js:121:27)
at Injector.loadInstance (/Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/injector.js:52:9)
at Injector.loadProvider (/Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/injector.js:74:9)
at async Promise.all (index 3)
at InstanceLoader.createInstancesOfProviders (/Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/instance-loader.js:44:9)
at /Users/davids/Developmet/nestjs/sync-user-preferences/node_modules/#nestjs/core/injector/instance-loader.js:29:13
O.K, after digging alot I found that the problem was caused because MongooseModule.forFeature name and #InjectModel() in user-preferences.service.ts value were not identical.
They must be identical.
Trying to use my ICommandBusAdapter.ts in my CreateUserAction.ts, but I get the following error:
[ExceptionHandler] Nest can't resolve dependencies of the ICommandBusAdapter (?). Please make sure that the argument at index [0] is available in the AdapterModule context
I have created a AdapterModule that will share all providers to others modules, but it doesn't seems work.
Any idea ?
AppModule.ts
import { UserModule } from './User/UserModule';
import { AdapterModule } from './Common/AdapterModule';
#Module({
imports: [AdapterModule, UserModule, // ...],
})
export class AppModule {}
AdapterModule.ts
import { CommandBusAdapter } from 'src/Infrastructure/Adapter/Bus/CommandBusAdapter';
const providers = [
{ provide: 'ICommandBusAdapter', useClass: CommandBusAdapter },
// ...
];
#Module({
providers: [...providers],
exports: [...providers],
})
export class AdapterModule {}
UserModule.ts
import { Module } from '#nestjs/common';
import { CreateUserAction } from 'src/Infrastructure/Action/User/CreateUserAction';
#Module({
controllers: [CreateUserAction],
})
export class UserModule {}
CommandBusAdapter.ts
import { CommandBus, ICommand } from '#nestjs/cqrs';
import { ICommandBusAdapter } from 'src/Application/Adapter/Bus/ICommandBusAdapter';
#Injectable()
export class CommandBusAdapter implements ICommandBusAdapter {
constructor(private readonly commandBus: CommandBus) {}
execute = (command: ICommand) => {
return this.commandBus.execute(command);
};
}
CreateUserAction.ts
import { ICommandBusAdapter } from 'src/Application/Adapter/Bus/ICommandBusAdapter';
export class CreateUserAction {
constructor(
#Inject('ICommandBusAdapter')
private readonly commandBus: ICommandBusAdapter,
) {}
// ...
Did you remember to add the CqrsModule to your application?
import { CqrsModule } from '#nestjs/cqrs';
#Module({
imports: [CqrsModule]
....
Without it there won't anything providing the CommandBus which you're trying to inject.
You can see an example here:
https://github.com/kamilmysliwiec/nest-cqrs-example/blob/master/src/heroes/heroes.module.ts
Please, I am new to angular2 and I need help implementing Johnny-Five in angular2.
I created a provider (J5Provider):
import { Injectable } from '#angular/core';
import 'rxjs/add/operator/map';
var raspi = require('raspi-io');
var j5 = require('johnny-five');
#Injectable()
export class J5Provider {
private board: any;
constructor() {
this.board = new j5.Board({
io: new raspi()
});
this.board.on('ready', function () {
var led = new j5.Led('P1-7');
led.strobe(500);
});
}
}
Then I tried to instantiate in app.module.ts in an Ionic2 project:
import { NgModule, ErrorHandler } from '#angular/core';
import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
import { MyApp } from './app.component';
import { AboutPage } from '../pages/about/about';
import { ContactPage } from '../pages/contact/contact';
import { HomePage } from '../pages/home/home';
import { TabsPage } from '../pages/tabs/tabs';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import {J5Provider} from '../providers/j5-provider'
#NgModule({
declarations: [
MyApp,
AboutPage,
ContactPage,
HomePage,
TabsPage
],
imports: [
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
AboutPage,
ContactPage,
HomePage,
TabsPage
],
providers: [
StatusBar,
SplashScreen,
J5Provider,
{provide: ErrorHandler, useClass: IonicErrorHandler}
]
})
export class AppModule {}
But when I run, I get the following error:
repl.js:1 Uncaught Error: Cannot find module "repl"
at v (polyfills.js:3)
at webpackMissingModule (repl.js:1)
at Object.<anonymous> (repl.js:1)
at Object.<anonymous> (repl.js:106)
at __webpack_require__ (bootstrap c6de802…:19)
at Object.<anonymous> (board.js:19)
at Object.<anonymous> (board.js:1269)
at __webpack_require__ (bootstrap c6de802…:19)
at Object.<anonymous> (accelerometer.js:1)
at Object.<anonymous> (accelerometer.js:1175)
at __webpack_require__ (bootstrap c6de802…:19)
at Object.noop (johnny-five.js:11)
at __webpack_require__ (bootstrap c6de802…:19)
at Object.<anonymous> (app.component.ts:8)
at __webpack_require__ (bootstrap c6de802…:19)
Please can anyone guide me on how I can do this implementation? Thanks in advance.
I have the following files: gist
The index.js attempts instantiate a base "Auth" class but in it's constructor the auth class acts as an object factory and passes back a subclass of Auth instead.
'use strict';
import Auth from './Auth';
let o = new Auth({type:'Oauth1'});
console.log(o);
o.getToken();
The Auth.js class definition is as follows:
'use strict';
import Oauth1 from './Oauth1';
export default class Auth {
constructor(config) {
if (this instanceof Auth) {
return new Oauth1(config);
} else {
this.config = config;
}
}
getToken() {
console.log('Error: the getToken module must be implemented in the subclass');
}
}
And the Oauth1.js class definition is:
'use strict';
import Auth from './Auth';
export default class Oauth1 extends Auth {
getToken() {
console.log('Auth: ', Auth);
}
}
When running with babel-node index.js I get the following error:
TypeError: Super expression must either be null or a function, not undefined
at _inherits (/repos/mine/test-app/Oauth1.js:1:14)
at /repos/mine/test-app/Oauth1.js:4:28
at Object.<anonymous> (/repos/mine/test-app/Oauth1.js:4:28)
at Module._compile (module.js:434:26)
at normalLoader (/usr/local/lib/node_modules/babel/node_modules/babel-core/lib/api/register/node.js:199:5)
at Object.require.extensions.(anonymous function) [as .js] (/usr/local/lib/node_modules/babel/node_modules/babel-core/lib/api/register/node.js:216:7)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
If I remove the extends expression from the Oauth1 class it executes but then I am not getting the inheritance I want.
Your issue has nothing to do with babel. The real problem is that you have circular dependencies in your code.
To resolve this issue you should remove Oauth1 dependency from its parent Auth class:
'use strict';
export default class Auth {
constructor(config) {
this.config = config;
}
getToken() {
console.log('Error: the getToken module must be implemented in the subclass');
}
}
'use strict';
import Auth from './Auth';
export default class Oauth1 extends Auth {
getToken() {
console.log('Auth: ', Auth);
}
}
If you don't want to remove this instanceof Auth check from your base class, you could require your Oauth1 subclass in run-time instead of importing it during module initialization:
constructor(config) {
if (this instanceof Auth) {
let Oauth1 = require('./Oauth1');
return new Oauth1(config);
}
this.config = config;
}