Nest js: Nest can't resolve dependencies of the Season3Service - javascript

I have the following error in nest. I've read the doc but I still don't understand what's going on. This is the full error: "[Nest] 9420 - 21/02/2022, 12:39:24 p. m. ERROR [ExceptionHandler] Nest can't resolve dependencies of the Season3Service (?). Please make sure that
the argument gModel at index [0] is available in the AppModule context". Here is my code:
app.controller.ts:
import { Controller, Get } from '#nestjs/common';
import { ClientRequest } from 'http';
import { AppService } from './app.service';
#Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
#Get()
getHello(): string {
return 'Sarani Mukoe! En el Arco de la Villa del Herrero';
}
}
app.module.ts:
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { Season3Controller } from './season3/season3.controller';
import { Season3Service } from './season3/season3.service';
import { Season3Module } from './season3/season3.module';
import { MongooseModule } from '#nestjs/mongoose';
#Module({
imports: [Season3Module, MongooseModule.forRoot('mongodb://127.0.0.1:27017/DemonSlayer')],
controllers: [AppController, Season3Controller],
providers: [AppService, Season3Service],
})
export class AppModule {}
app.service:
import { Injectable } from '#nestjs/common';
#Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
Then, I have the season3 module folder:
season3.controller.ts:
import { Controller, Get, Post, Put, Delete, Body, Param } from '#nestjs/common';
import { CreateSeasonDto } from './dto/create-season.dto';
import { Season } from './interfaces/Season';
import { Season3Service } from "./season3.service";
#Controller('season3')
export class Season3Controller {
constructor(private season3: Season3Service) {}
#Get()
getSeasons(): Promise<Season[]> {
return this.season3.getSeasons();
}
#Get(':p')
getSeason(#Param('p') id: string): Promise<Season>{
console.log(id);
return this.season3.getSeason(id);
}
#Post()
createSeason(#Body() season: CreateSeasonDto): string {
console.log(
`Título: ${season.titulo}. Cuerpo: ${season.cuerpo}. Realizado: ${season.realizado}`
);
return 'Insertando.... Hinokami Kagura';
}
#Put(':p1')
updateSeason(#Body() cuerpo: CreateSeasonDto, #Param('p1') id): string {
console.log(cuerpo);
console.log(id);
return `Actualizando.... Velocidad Extrema`;
}
#Delete(':id')
deleteSeason(#Param('id') id): string {
console.log(id);
return `Eliminando(${id}) .... Colmillos Afilados`;
}
}
season3.module.ts:
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { Season3Controller } from './season3.controller';
import { Season3Service } from './season3.service';
import { SeasonSchema} from "./schemas/season.schema";
#Module({
imports: [MongooseModule.forFeature([
{name:'g', schema:SeasonSchema}
])],
controllers: [Season3Controller],
providers: [Season3Service],
})
export class Season3Module {}
season3.service.ts:
import { Model } from "mongoose";
import { Injectable } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import { Season } from "./interfaces/Season";
#Injectable()
export class Season3Service {
constructor(#InjectModel('g') private seasonModel: Model<Season>) {}
async getSeasons() {
return await this.seasonModel.find();
}
async getSeason(id: string) {
return await this.seasonModel.findById(id);
}
}

It looks like Season3Service is not exported so you won't be able to use it in other modules.
in season3.module.ts add export
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { Season3Controller } from './season3.controller';
import { Season3Service } from './season3.service';
import { SeasonSchema} from "./schemas/season.schema";
#Module({
imports: [MongooseModule.forFeature([
{name:'g', schema:SeasonSchema}
])],
controllers: [Season3Controller],
providers: [Season3Service],
exports: [Season3Service], // <----- make Season3Service public
})
export class Season3Module {}
doc: https://docs.nestjs.com/modules#shared-modules
After this, any other module that imports Season3Module will be able to inject (user) Season3Service
in app.module.ts
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { Season3Controller } from './season3/season3.controller';
import { Season3Module } from './season3/season3.module';
import { MongooseModule } from '#nestjs/mongoose';
#Module({
imports: [Season3Module, MongooseModule.forRoot('mongodb://127.0.0.1:27017/DemonSlayer')],
controllers: [AppController, Season3Controller],
providers: [AppService], // <---- remove Season3Service from providers
})
export class AppModule {}
Now any providers/controllers in AppModule will have access to Season3Service

Related

Everything is imported but Nest can't resolve dependencies of the stripePaymentService

I am integrating Stripe payment gateway through NestJS. I am getting the error which says "Nest can't resolve dependencies of the stripePaymentService". Although I am quite familiar with this error but somehow things are not working for me. I believe everything is imported where it should be.
This is complete error:
Error: Nest can't resolve dependencies of the stripePaymentService (?). Please make sure that the argument paymentIntentRepository at index [0] is available in the AppModule context.
Potential solutions:
- Is AppModule a valid NestJS module?
- If paymentIntentRepository is a provider, is it part of the current AppModule?
- If paymentIntentRepository is exported from a separate #Module, is that module imported within AppModule?
My stripePaymentModule is
/* eslint-disable prettier/prettier */
import { Module } from '#nestjs/common';
import { stripePaymentController } from './stripe-payment.controller';
import { stripePaymentService } from './stripe-payment.service';
import { TypeOrmModule } from '#nestjs/typeorm';
import { paymentIntent } from './entities/paymentIntent.entity';
import { ConfigModule } from '#nestjs/config';
#Module({
imports:[
ConfigModule.forRoot({
isGlobal: true,
}),
TypeOrmModule.forFeature([paymentIntent])],
controllers: [stripePaymentController],
providers: [stripePaymentService],
exports: [stripePaymentService],
})
export class stripePaymentModule {}
stripePaymentServices is
/* eslint-disable prettier/prettier */
import { Injectable, Logger } from '#nestjs/common';
import { InjectStripe } from 'nestjs-stripe';
import { ConfigService } from '#nestjs/config';
import Stripe from 'stripe';
import { paymentIntent } from './entities/paymentIntent.entity';
import { InjectRepository } from '#nestjs/typeorm';
import { Repository } from 'typeorm';
#Injectable()
export class stripePaymentService {
stripe: Stripe;
logger = new Logger(stripePaymentService.name);
constructor(
#InjectRepository(paymentIntent)
private readonly paymentIntent:Repository<paymentIntent>,
)
{const stripeApiKey = process.env.STRIPE_SECRET_KEY;
this.stripe = new Stripe(stripeApiKey, {
apiVersion: '2022-11-15',
});}
async payment_intent(data: any, user) {
const intent = await this.stripe.paymentIntents.create({
amount: data.amount,
currency: data.currency,
description: data.description,
payment_method_types: ['card'],
});
return await this.paymentIntent.save({'userId':user.userId, 'intent_response':JSON.stringify(intent)})
// return intent;
}
}
And finally this is app.module
/* eslint-disable prettier/prettier */
import { Module } from '#nestjs/common';
import { UsersModule } from './users/users.module';
import { ConfigModule, ConfigService } from '#nestjs/config';
import { TypeOrmModule } from '#nestjs/typeorm';
import { AuthModule } from './auth/auth.module';
import { User } from './users/entities/user.entity';
import { PassportModule } from '#nestjs/passport';
import { MailModule } from './mail/mail.module';
import { FlightBookingModule } from './flight-booking/flight-booking.module';
import { TravelBookings } from './flight-booking/entities/bookingToken.entity';
import { stripePaymentService } from './stripe/stripe-payment.service';
import { stripePaymentController } from './stripe/stripe-payment.controller';
import { StripeModule } from 'nestjs-stripe';
import { stripePaymentModule } from './stripe/stripe-payment.module';
import { paymentIntent } from './stripe/entities/paymentIntent.entity';
#Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
StripeModule.forRoot({
apiKey: process.env.STRIPE_API_KEY,
apiVersion: '2022-11-15'
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
type: 'postgres',
host: configService.get('DB_HOST'),
port: +configService.get<number>('DB_PORT'),
username: configService.get('DB_USERNAME'),
password: configService.get('DB_PASSWORD'),
database: configService.get('DB_NAME'),
entities: [User, TravelBookings, paymentIntent],
synchronize: true,
}),
inject: [ConfigService],
}),
PassportModule,
UsersModule,
AuthModule,
MailModule,
FlightBookingModule,
stripePaymentModule
],
controllers: [stripePaymentController],
providers: [stripePaymentService],
})
export class AppModule {}
The error is thrown from AppModule context. You wouldn't need to put stripePaymentService as a provider in AppModule.
If stripePaymentService is used by other modules, once you have export it, you just need to import the related module in a module that you want, and that would be enough.
So all you need to do is remove these lines from AppModule:
providers: [stripePaymentService]
You can remove this line as well:
controllers: [stripePaymentController]

Unable to add auth0 authentication to a graphql based nestjs app

I want to add authentication to my graphql app in nestjs. the token I receive is from auth0.
Im fairly new to nestjs I have looked at its documentation. this is the best I could comeup with and it still isnt working
this is my code where Im trying to add auth
app.module
import { Module } from '#nestjs/common';
import { ConfigModule } from '#nestjs/config';
import { MongooseModule } from '#nestjs/mongoose';
import { databaseConfig, applicationConfig } from '../../config/';
import MongoServiceClass from '../../services/Mongo';
import { ConfigModule as AppConfigModule } from '../config/config.module';
import { GraphQLModule } from '#nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '#nestjs/apollo';
import { LoggingPlugin } from 'src/plugins/LoggerCustom';
import { UserModule } from './user/user.module';
import { QuotaModule } from './quota/quota.module';
import { QuotaManagementModule } from './quota-management/quota-management.module';
import { BobModule } from './bob/bob.module';
import { SlModule } from './sl/sl.module';
import { SlQModule } from './sl-q/sl-q.module';
import { AuthModule } from '../auth/auth.module';
const NODE_ENV = process.env.NODE_ENV;
#Module({
imports: [
LoggingPlugin,
ConfigModule.forRoot({
load: [applicationConfig, databaseConfig],
envFilePath: `.env.${NODE_ENV}`,
isGlobal: true,
}),
MongooseModule.forRootAsync({
useClass: MongoServiceClass,
}),
AuthModule,
GraphQLModule.forRoot<ApolloDriverConfig>({
autoSchemaFile: 'schema.gql',
driver: ApolloDriver,
path: '/graphql',
playground: true,
debug: true,
}),
BobModule,
QuotaModule,
QuotaManagementModule,
AppConfigModule,
SlQModule,
SlModule,
UserModule,
],
})
export class AppModule {}
auth.module
import { Global, Module } from '#nestjs/common';
import { UserModule } from '../app/user/user.module';
import { AuthService } from './auth.service';
import { AuthResolver } from './auth.resolver';
import { GqlAuth0Guard } from './gql.guard';
import { GqlAuth0JwtStrategy } from './gql-auth0-jwt.strategy';
import { PassportModule } from '#nestjs/passport';
#Global()
#Module({
imports: [UserModule, PassportModule.register({ defaultStrategy: 'jwt' })],
providers: [AuthService, AuthResolver, GqlAuth0JwtStrategy, GqlAuth0Guard],
})
export class AuthModule {}
gql-auth0-jwt.strategy
import { Injectable, UnauthorizedException } from '#nestjs/common';
import { PassportStrategy } from '#nestjs/passport';
import { Strategy as BaseStrategy, ExtractJwt, VerifiedCallback } from 'passport-jwt';
import { passportJwtSecret } from 'jwks-rsa';
#Injectable()
export class GqlAuth0JwtStrategy extends PassportStrategy(BaseStrategy) {
domain = 'https://dev-ab454a.us.auth0.com/';
constructor() {
super({
secretOrKeyProvider: passportJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: `https://dev-ab454a.us.auth0.com/.well-known/jwks.json`,
}),
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
audience: 'https://hyyype-app.herokuapp.com/',
issuer: 'https://dev-ab454a.us.auth0.com/',
});
}
validate(payload: any, done: VerifiedCallback) {
console.log('Validate JWT-STRATEGY');
if (!payload) {
done(new UnauthorizedException(), false);
}
return done(null, payload);
}
}
gql.guard
import { ExecutionContext, Injectable } from '#nestjs/common';
import { GqlExecutionContext } from '#nestjs/graphql';
import { AuthGuard } from '#nestjs/passport';
#Injectable()
export class GqlAuth0Guard extends AuthGuard('jwt') {
getRequest(context: ExecutionContext) {
console.log('GQL-AUTH0-GUARD');
const ctx = GqlExecutionContext.create(context);
return ctx.getContext().req;
}
}
auth.resolver
import { UnauthorizedException, UseGuards } from '#nestjs/common';
import { Query, Resolver } from '#nestjs/graphql';
import { CurrentUser } from './auth.decorator';
import { GqlAuth0Guard } from './gql.guard';
#Resolver()
export class AuthResolver {
#Query(() => String)
#UseGuards(GqlAuth0Guard)
getAuthenticatedUser(#CurrentUser() user: any) {
if (!user) {
throw new UnauthorizedException('Get Auth User');
}
return user;
}
}
this is my response after i send a request I have checked the token is valid
GQL-AUTH0-GUARD
error: 586ms - Unauthorized

How to fix NestJS #InjectModel() dependency error?

rememberLink.scheme.ts
import { Prop, Schema, SchemaFactory } from '#nestjs/mongoose';
import { Document, Types } from 'mongoose';
import { User } from 'src/users/schemas/users.schema';
export type RememberLinkDocument = RememberLink & Document;
#Schema({versionKey: false, timestamps: true})
export class RememberLink {
#Prop({ type: String, required: true })
code: string;
#Prop({ type: Types.ObjectId, ref: User.name, required: true })
user: User;
}
export const RememberLinkSchema = SchemaFactory.createForClass(RememberLink);
remember-password.module.ts
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { RememberPasswordController } from './remember-password.controller';
import { RememberPasswordService } from './remember-password.service';
import { RememberLink, RememberLinkSchema } from './schemas/rememberLink.schema';
#Module({
imports: [
MongooseModule.forFeature([{
name: RememberLink.name,
schema: RememberLinkSchema
}])
],
controllers: [RememberPasswordController],
providers: [RememberPasswordService],
exports: [RememberPasswordService]
})
export class RememberPasswordModule {}
remember-password.service.ts
import { Injectable } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import { Model } from 'mongoose';
import { UserDto } from 'src/users/dto/user.dto';
import { User } from 'src/users/schemas/users.schema';
import { RememberLinkDto } from './dto/rememberLink.dto';
import { RememberLink, RememberLinkDocument } from './schemas/rememberLink.schema';
#Injectable()
export class RememberPasswordService {
constructor( #InjectModel(RememberLink.name) private readonly rememberLinkModel: Model<RememberLinkDocument> ) {}
async getUserByRememberCode(code: string): Promise<UserDto> {
return await this.rememberLinkModel.findOne({code}).populate(User.name).lean();
}
}
Error:
Nest can't resolve dependencies of the RememberPasswordService (?).
Please make sure that the argument RememberLinkModel at index [0] is
available in the RememberPasswordService context.
What I would do is export the MongooseModule as well, Its just that the dependency injection knows that there will be Separate module for that model somewhere in the App
#Module({
imports: [
MongooseModule.forFeature([{
name: RememberLink.name,
schema: RememberLinkSchema
}])
],
controllers: [RememberPasswordController],
providers: [RememberPasswordService],
exports: [MongooseModule,RememberPasswordService] // <-- MongooseModule added here
})
export class RememberPasswordModule {}
Fixed. It was import "RememberPasswordService" instead of "RememberPasswordModule" in another module

How to use global module after imported?

I've followed the example from the docs on how to create a basic config service.
At the bottom of the tutorial it says you can opt to declare it globally:
"Instead of importing ConfigModule repeatingly in all your modules, you can also declare ConfigModule as a global module."
So following the documentation for global modules I have:
Imported Global from #nestjs/common into ConfigModule.
Added the #Global() decorator to ConfigModule.
Imported ConfigModule into AppModule.
Added ConfigModule to the imports array.
So what's next? I have tried to inject ConfigService into AppService however it doesn't resolve.
app.module.ts:
import { Module } from '#nestjs/common';
import { AppService } from './app.service';
import { AppController } from './app.controller';
import { ConfigModule } from '../config/config.module';
#Module({
imports: [
ConfigModule,
],
controllers: [
AppController,
],
providers: [
AppService,
],
})
export class AppModule {}
app.service.ts:
import { Injectable } from '#nestjs/common';
#Injectable()
export class AppService {
private readonly config: ConfigService;
constructor(config: ConfigService) {
this.config = config;
}
getHello(): string {
return config.get('DB_NAME');
}
}
config.module.ts:
import { Module, Global } from '#nestjs/common';
import { ConfigService } from './config.service';
#Global()
#Module({
providers: [
{
provide: ConfigService,
useValue: new ConfigService(`${process.env.NODE_ENV}.env`),
},
],
exports: [
ConfigService,
],
})
export class ConfigModule {}
config.service.ts:
import * as dotenv from 'dotenv';
import * as fs from 'fs';
export class ConfigService {
private readonly envConfig: { [key: string]: string };
constructor(filePath: string) {
this.envConfig = dotenv.parse(fs.readFileSync(filePath));
}
get(key: string): string {
return this.envConfig[key];
}
}
I expect to be able to inject ConfigService and access it from any module.
You're missing the this qualifier in your AppService:
getHello(): string {
return this.config.get('DB_NAME');
^^^^^
}
Also, the import is missing:
import { ConfigService } from './config/config.service';

How to prompt user when he tries to move out of any component in angular 6

I have a payment page with payment component as -
import { Component, OnInit } from '#angular/core';
import { PayPalConfig, PayPalEnvironment, PayPalIntegrationType } from 'ngx-paypal';
import { AppService } from '../app.service';
import { Payment } from '../models/payment.model';
import { Router } from '#angular/router';
#Component({
selector: 'app-payment',
templateUrl: './payment.component.html',
styleUrls: ['./payment.component.css']
})
export class PaymentComponent implements OnInit {
//totalpay:number;
payment:Payment;
changesSaved=false;
constructor(private appservice:AppService,private router:Router) { }
ngOnInit() {
this.initConfig();
}
hasChanges(){
return true;
} }
Now I want to prompt user if he tries to move back or try to click any link ,without clicking on paypal payment button in payment component ,I have used Candeactivate by making paymentguard.ts
import { Injectable } from '#angular/core';
import { CanDeactivate } from '#angular/router';
import { PaymentComponent } from './payment/payment.component';
import { PaymentGuard} from './payment/payment.guard';
#Injectable()
export class ConfirmDeactivateGuard implements CanDeactivate<PaymentComponent> {
canDeactivate(target: PaymentComponent) {
if (target.hasChanges()) {
return window.confirm('Do you really want to cancel?');
}
return true;
}
}
And this is my routing in app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { BannerComponent } from './banner/banner.component';
import { ProductsComponent } from './products/products.component';
import { BodyComponent } from './body/body.component';
import { BestsellersComponent } from './bestsellers/bestsellers.component';
import { FooterComponent } from './footer/footer.component';
import { BenefitComponent } from './benefit/benefit.component';
import { CombinedComponent } from './combined/combined.component';
import { CartComponent } from './cart/cart.component';
import { StorageServiceModule} from 'angular-webstorage-service';
import { FormsModule } from '../../node_modules/#angular/forms';
import { NgxPayPalModule } from 'ngx-paypal';
import { HttpClientModule } from '#angular/common/http';
import { AboutComponent } from './about/about.component';
import { ContactComponent } from './contact/contact.component';
import { PaymentComponent } from './payment/payment.component';
import { AuthGuard } from './auth.guard';
import { FlashMessagesModule } from 'angular2-flash-messages';
import { FinalstatusComponent } from './finalstatus/finalstatus.component';
import { ConfirmDeactivateGuard } from './payment.guard';
import { PaymentfailComponent } from './paymentfail/paymentfail.component';
const routes: Routes = [
{ path: 'cart', component: CartComponent },
{ path: 'about', component: AboutComponent },
{ path: '', component: CombinedComponent },
{ path: 'payment', component: PaymentComponent,canActivate:[AuthGuard],canDeactivate[ConfirmDeactivateGuard]},
{ path: 'orderstatus', component: FinalstatusComponent,canActivate:[AuthGuard] },
{ path: 'paymentfail', component: PaymentfailComponent,canActivate:[AuthGuard] },
{ path: 'contact', component: ContactComponent },
];
#NgModule({
declarations: [
AppComponent,
HeaderComponent,
BannerComponent,
ProductsComponent,
BodyComponent,
BestsellersComponent,
FooterComponent,
BenefitComponent,
CombinedComponent,
CartComponent,
AboutComponent,
ContactComponent,
PaymentComponent,
FinalstatusComponent,
PaymentfailComponent,
],
imports: [
BrowserModule,
RouterModule.forRoot(routes),
StorageServiceModule,
FormsModule,
NgxPayPalModule,
HttpClientModule,
FlashMessagesModule.forRoot()
],
providers: [AuthGuard],
bootstrap: [AppComponent]
})
export class AppModule { }
I don't know why it is not working ,any idea how to achieve it???
Your CanDeactivate route guard must return one of: boolean, Promise, Observable.
In your case, it is best you use the later because your rely on the user taking an action to decide if CanDeactivate care run or not. This makes your guard asynchronous.
Because the method must always return the same type, the !hasChanges() myst also return an observable.
Try this code below:
import { Observable, create } from 'rxjs';
import { Injectable } from '#angular/core';
import { CanDeactivate } from '#angular/router';
import { PaymentComponent } from './payment/payment.component';
import { PaymentGuard} from './payment/payment.guard';
#Injectable()
export class ConfirmDeactivateGuard implements CanDeactivate<PaymentComponent> {
canDeactivate(target: PaymentComponent): Observable<boolean> {
return Observable.create(function(observer) {
if (!target.hasChanges()) {
observer.next(true);
} else if(window.confirm('Do you really want to cancel?')) {
observer.next(true);
} else {
observer.next(false);
}
});
}
}
I hope this helps!
Edit: I moved everything inside of the observer

Categories

Resources