NestJs dependency injection with task scheduling is not working as singleton - dependency-injection

I already checked the link NestJs dependency injection with task scheduling is not working but that is not the same problem that I have since I'm not using request scope on the on my injectable service.
I recorded a loom video to show the issue.
https://www.loom.com/share/37875a6e0d79400698a4408ef8d9ac89
Thanks
Tiago

Solved. Thanks to #Micael Levi.
The problem was the provider array on AppModule. It was instantiating the ReckonService again.
Example of the ReckonModule after fix:
#Module({
imports: [HttpModule],
controllers: [ReckonController],
providers: [ReckonService],
exports: [ReckonService],
})
export class ReckonModule {}
Example of the AppModule after fix:
#Module({
imports: [ReckonModule],
controllers: [],
providers: [AppService],
})
export class AppModule {}
Thanks
Tiago

Related

NestJS: DI and class inheritance

I am running into issues getting the proper class injected with NestJS. There is a base class #Injectable() export class FakeBinanceClient implements ITradeClient {... and a child class #Injectable() export class ScheduledFakeBinanceClient extends FakeBinanceClient {...
I do inject the child explicitely in another class by constructor(#Inject(ScheduledFakeBinanceClient) tradeClient: ITradeClient, .... However, the FakeBinanceClient base class gets injected.
The main module also states clearly to use the child class:
#Module({
imports: [
...
],
controllers: [],
providers: [ScheduledFakeBinanceClient, ... (no FakeBinanceClient)]
})
export class AppModule {}
Any idea whe the child class isn't being injected?
Wasn't a code problem. I simply had to delete the dist-folder and rebuild.

Angular 5: Can't resolve all parameters for component

I've encountered a problem with injecting services in angular 5 as in tutorial.
I have a simple service
#Injectable()
export class SimpleService {
...
}
And a simple component:
#Component({...})
export class SimpleComponent {
constructor(private simpleService SimpleService) {}
}
A service is set to providers in module:
#NgModule({
...
providers: [SimpleService]
...
})
export class SimpleModule {}
I see the following error in console:
Error: Can't resolve all parameters for SimpleComponent
However, if I inject the SimpleService with #Inject like
#Inject(SimpleService) private simpleService: SimpleService
the error disappears.
What am I doing wrong?
UPDATE:
I saw several answers where people advise to add emitDecoratorMetadata: true to tsconfig file. But this line is already there
It turned out that the reason for this error was an incorrect import of polyfills.ts. Previously I ejected my cli app and removed polyfills entry point from my webpack config. After that I imported them in my main.ts. But I imported polyfills after I imported AppModule. After I moved import './polyfills.ts' statement to the top of the file the error disappeared.
Another option for fixing this error is moving to AOT compilation:
module: {
rules: [
...
{
"test": /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
"use": [
"#ngtools/webpack"
]
}
]
}
plugins: [
...
new AngularCompilerPlugin({
mainPath: 'main.ts',
platform: PLATFORM.Browser,
hostReplacementPaths: {
'environments/environment.ts': 'environments/environment.ts'
},
sourceMap: true,
tsConfigPath: 'src/app/tsconfig.json',
skipCodeGeneration: false // this line is responsible for AOT
})
]
If you use AOT compilation instead JIT you won't need emitDecoratorMetadata in your tsconfig.
I had a similar issue and this may help others, as this was the closest match I found while searching.
I had an error in my constructor function. I forgot to declare the type of the Service:
I had written:
constructor(
private myService
){}
instead of:
constructor(
private myService: MyService
){}

DomPopupSourceFactory provider error when using material-dropdown-select

I am trying to use material dropdown select but I am getting this error:
EXCEPTION: No provider found for DomPopupSourceFactory.
The materialDirectives is added to the directives list, the html call is simple:
<material-dropdown-select></material-dropdown-select>
I tried the angular_components_example and it worked fine. The problem is with my project. I already tried to clean the .packages and executed the pub get. Nothing worked. I tried some other material components and they worked.
If you add materialProviders to AppComponent it should work:
#Component(
selector: 'my-app',
directives: const <dynamic>[
CORE_DIRECTIVES,
materialDirectives,
],
providers: const <dynamic>[
materialProviders, // <<<<<<<<<<<<<<<<
],
)
class AppComponent {...}
It works in angular_components example because the app-level component includes the necessary popupBindings provider.
If you aren't including materialProviders in your app, you can use a more specific provider in your components.
Here is the minimum boilerplate required for using material-dropdown-select:
import 'package:angular/angular.dart';
import 'package:angular_components/laminate/popup/module.dart';
import 'package:angular_components/material_select/material_dropdown_select.dart';
#Component(
selector: 'my-dropdown-select',
directives: const [
MaterialDropdownSelectComponent,
],
providers: const [
popupBindings,
],
)
class MyDropdownSelectComponent {}

Angular2 - inject singleton Service into Directive

I have problem with injecting singleton service into a directive.
I have service:
#Injectable()
export class AuthService{ ... }
I put it into bootstrapper.
bootstrap(AppComponent, [AuthService, ...]);
I made directive, that protects my component:
#Directive({
selector: '[protected]'
})
export class ProtectedDirective {
constructor(private authService:AuthService) { ... }
}
... and added to one of components
#Component({
selector: 'dashboard',
directives: [ProtectedDirective],
template: '<div protected></div',
})
export class DashboardCmp { }
In console i see an error:
ORIGINAL EXCEPTION: No provider for AuthService!
If I add a provider to DashboardCmp, everything works fine, but it's not a singleton service. I set its properties in other component and I don't see them when I'm in directive.
I resolved my problem. Everything was fine but
import {AuthService} from '../services/auth.service'; (in protected.directive.ts)
is not equal to
import {AuthService} from '../Services/auth.service'; ( in main.ts)
Yes, it's stupid, but it made the dependency injection impossible.

Angular2 Beta dependency injection

I have a NavBar Component which loads the QApi Service, the QApi Service loads the UserService, but I get the following error:
EXCEPTION: No provider for UserService! (NavBarComponent -> QApi -> UserService)
Either I simply don't get the concept of dependency injection, I made a stupid error, or this is just way to complicated compared to native development... Thanks for your help.
Here my code:
UserService:
import {Injectable} from 'angular2/core';
//import {User} from '../data-source-mocks/users';
#Injectable()
export class UserService {
public isAuthenticated = true;
}
QApi Service:
import {Injectable} from 'angular2/core';
import {UserService} from '../user/user.service';
#Injectable()
export class QApi {
constructor(private _userService: UserService) {}
}
NavBar Component:
import {Component} from 'angular2/core';
import {QApi} from '../../services/q-api/q-api';
#Component({
selector: 'nav-bar',
template: `Test NavBar`,
providers: [QApi]
})
export class NavBarComponent {
private _isAuthenticated = false;
constructor(private _QApi: QApi) {}
}
EDIT:
First of all: Thanks for alle the great answers each and every single one helped me to understand dependency injection better, especially this article: https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html
I changed my QApi class to this:
import {Injectable, Inject, Injector} from 'angular2/core';
import {UserService} from '../user/user.service';
import {CardService} from '../card/card.service';
#Injectable()
export class QApi {
constructor() {
var _injector = Injector.resolveAndCreate([UserService,
CardService]);
this.userService = _injector.get(UserService);
this.cardService = _injector.get(CardService);
}
}
Now it works like I hoped it would. Cant thank you guys enough!!
Add UserService to the component providers:
#Component({
selector: 'nav-bar',
template: `Test NavBar`,
providers: [QApi, UserService] // <- add UserService here
})
export class NavBarComponent { /* ... */ }
Here are two good articles to better understand Angular2 Dependency Injection:
blog.thoughtram.io: Dependency Injection in Angular2
blog.thoughtram.io: Injecting services in services in Angular 2
In fact both previous responses are true! ;-)
You need to define the services:
Application level. Within the second parameter of the bootstrap function. It contains the list of the providers that are available for the whole application.
bootstrap(App, [UserService, QApi, ...]);
Component level. Within the providers attribute of the Component annotation. In this case, this is only configured for this component and you need to define this for each component where the QApi service.
#Component({
selector: 'nav-bar',
template: `Test NavBar`,
providers: [QApi, UserService]
})
You also mix things. I mean you can put the UserService provider at the application level and QApi at the component level. In fact what is important is that Angular can find providers for all the involved elements in the processing chaining (with dependency injection). They can come from either component level (1st) or application level (2nd).
Hope that it gives you some additional hints following alexpods and MichaelOryl great answers ;-)
Thierry
List the services in your bootstrap call (wherever you are handling that). Something like the following should work:
bootstrap(App, [UserService, QApi, COMMON_DIRECTIVES, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, HTTP_PROVIDERS]);
providers// directives added here are available to all children
Then you will have a single instance of each of those services available to the rest of your application.

Resources