NestJs instantiate class with dependencies - node.js

I'm completely new to Nestjs moving from Laravel, really enjoying it, but it's kinda more difficult to find answers online.
I got a base class with a dependency of the HttpService:
export abstract class BaseClass {
constructor(protected httpService: HttpService) {}
}
I got a couple of classes extending the base class, and I'm trying to instantiate them on the fly:
const bus = new BusClass([
new classNumber1(this.httpService),
new classNumber2(this.httpService),
]);
I want to find a way to NOT pass the httpService to the constructors,
just like NestJs doing it when we inject services on the constructors in the controllers for example.
I tried with factories and really any example from the docs, with no success.
Will be glad for any kind of help, thanks allot ahead!

Related

Inheritance or Injecting in Typescript

I create an large project with using Typescript and NestJS framework, I want to create this project in OOP architecture and I have a want important question about it. I want to create one, base service with commons function that will be use in almost every service in the project, and I have a two ways to using a common parts.
First is to create an abstract class with commons methods like below:
export abstract class BaseService {}
and inheritance this abstract class in the target service:
export class UserService extends BaseService {}
Thanks of this I can use all of the methods that exists in BaseService with using this keyword and creating an reference to the function.
But I have a second approach, with using Injecting service via constrcutor:
export class BaseService {}
and injecting via constructor:
export class UserService {
constructor (
private readonly baseService: BaseService
){}
someMethod(): void {
return baseService.getHelloWorld();
}
}
In this way I can to create an reference stricte from injecting service.
And now i have a question. Which approach is better in the large project?
PS. I prefer to create an generic function based on <T> on methods instead of class
In this particular case delegation to an injected service is more appropriate. If you do this, you should probably rename BaseService to something that does not imply that it is a base class to be inherited by other service classes. I suggest SharedService or CommonService.
Delegation is better here because your design suggests that the BaseService and UserService do not have the same meaning and purpose but only have common operations. Reducing code duplication should not be the main justification for choosing inheritance.

NestJs: How can I import one repository into another?

I apologize for what is likely a very amateur question. Coming from Laravel, this is still quite confusing to me and I just don't understand what is needed.
I have a user.repository.ts file and a location.repository.ts file. Each have their own modules, controllers and services. I have successfully created CRUD operations for each entity but now am trying to work towards a Many to Many relationship.
In my user.repository.ts file, I am trying to save a related (many to many) repository:
// user.repository.ts
user.locations = await this.locationRepository.findByIds(locations);
...
await user.save();
I am not sure how to inject or import the location.repository.ts file. I have tried numerous variations of importing the service into each module. Or importing each module into the other module. I have tried different versions of this:
#EntityRepository(User)
#EntityRepository(Location)
Or importing the LocationService into the UserService.
In Laravel, this would be as "simple" as $model->sync($relationship);
How can I import/inject the locationRepository into my userRepository? Thank you for any suggestions!
I assume this question is related to your last question, the simplest way to implement it, Add Locationentity to your UserModule
#Module({
imports:[TypeOrmModule.forFeature([UserRepository,LocationRepository])], // or just Location entity [UserRepository,Location] if you didn't setup a custom LocationRepository
After that, inject it in your as what you did for userRepo... service
constructor(
#InjectRepository(LocationRepository)
private locationRepository: LocationRepository,
// or just private locationRepository: Repository<Location>,
) {}
In the create method service get your locations:
async createUser(createUserDto: CreateUserDto) { // usersSrvice
let locations = await this.locationRepository.findByIds(createUserDto.locations);
await this.userRepository.createMethodeName(createUserDto,locations) // add secand
params for your locations
don't hesitate to ask if you have any other questions

When to use ExceptionFilter vs BaseExceptionFilter in NestJS?

What is the diff b/w both types of filters. And when to use what? Please explain with any example
#Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
}
#Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
}
ExceptionFilter is an interface that defines that the current class should implement the catch method with the signature (exception: unknown, host: ArgumentHost).
BaseExceptionFilter is a class already made in NestJS with a working catch method. By using extend you can add your own logic to catch and then in the end of the implementation call super.catch(exception, host) and let Nest take care of the rest from there.
The main difference of the two is how much of the logic do you want to write vs how much do you want to add in. If you are happy with how Nest already handles errors, and just want to add in the ability to log your errors, say to a database, then extends BaseExceptionFilter is a good fit. However, if you don't care or how Nest's exception filter works by default, then implements ExceptionFilter and writing your own custom logic is the way to go.

What is the best way to organize the code of a nodejs-express project, using TypeScript?

While trying to organize the code of my first NodeJS-express project, I ran into some doubts about the use of namespaces, modules and classes. When to choose one? When another?
For example, my project is structured (simplifying) in.
routers -> controllers -> services -> repositories.
The possibilities I thought of to manage these "entities" are the following:
Classes
Classes with static methods
Singletons
Simple module export
Namespaces
Classes
I thought of avoiding them right away, since the above-mentioned entities do not need to memorize any state. Furthermore, they would complicate the code due to the need to be instantiated.
Classes with static methods
They are correct? Or rather a simple namespace or simple export of the modules?
Class + Singletons
A way of organizing the code in a "nicer" way than the simple class, but which does not convince me, since reading on the net that the singleton in TypeScript is replaceable with the namespace.
Simple module export
The way I thought to implement immediately, for example in this way (file user.repository.ts):
const add = async (user: User): Promise<void> => {
if(await canBeAdded(user)) {
//save user;
} else {
// throw error
}
}
export const UserRepository = {
add
}
It's corrects? Or am I not properly using what TypeScript offers? Being the first time I use this language, I would like to be sure I chose the right path.
Namespaces
Are they a better choice to develop the code published above? Are you advised against?
Thank you in advance for the answers! Any advice is welcome!
P.S. I know that, once the TypeScript is compiled, in Javascript the classes are practically syntactic sugar. What I'm interested in knowing are the best practices for writing good code in TypeScript.

Stripe + TypeScript: How to extend #types/stripe definitions for stripe-node?

I'm working on project, where we're using Stripe library for Node. We also want to use TypeScript on this project.
I've figured out that Stripe isn't providing official TypeScript definitions but I've found some community definitions #types/stripe on NPM. So I installed them and after a while I got an error:
Property 'sources' does not exist on type 'Stripe'.
Well there are missing some definitions, for example for this stripe.sources-related functionality.
I want to add missing definitions locally. So I need to extend this file:
#types/stripe/index.d.ts
I think that for the problem above I need:
to add property sources: Stripe.resources.Sources; to class Stripe,
to add class Sources to namespace resources,
to add missing function declarations to class Sources.
The problem is that I really don't know how. How should the .d.ts file with extensions look like? I've made many attempts according some examples and TypeScript docs but it always doesn't work. Do you have any idea?
I don't believe there's a way to augment the export-assigned Stripe class; the problem is similar to this open issue about augmenting a default-exported class. At this time, since you can't use augmentation, you'll have to fork the #types/stripe definitions for your project, and then you may as well make all the desired changes that way.
I think my colleague has found a solution that works for me. Here is how he made it:
import ST from 'stripe'
declare module 'stripe' {
namespace sources {
interface ISource extends IResourceObject {
...
}
interface ISourceCreationData {
...
}
}
namespace resources {
class Sources {
create(data: sources.ISourceCreationData): Promise<sources.ISource>;
retrieve(source: string, client_secret?: string): Promise<sources.ISource>;
}
}
class Stripe extends ST {
sources: ST.resources.Sources;
}
}

Resources