Je suis nouveau à angular. J'ai créé une application Web à l'aide de vs2015 et des derniers packages angulaires . Lorsque j'essaie d'appeler mon service à partir d'un composant sur un clic sur un événement, je reçois une erreur ci-dessous dans la fenêtre de la console du navigateur.
Erreur: -
ERROR Error: Uncaught (in promise): Error: StaticInjectorError[ViewCountService]:
StaticInjectorError[ViewCountService]:
NullInjectorError: No provider for ViewCountService!
Error: StaticInjectorError[ViewCountService]:
StaticInjectorError[ViewCountService]:
NullInjectorError: No provider for ViewCountService!
at _NullInjector.get (injector.js:31)
at resolveToken (injector.js:387)
at tryResolveToken (injector.js:330)
at StaticInjector.get (injector.js:170)
at resolveToken (injector.js:387)
at tryResolveToken (injector.js:330)
at StaticInjector.get (injector.js:170)
at resolveNgModuleDep (ng_module.js:103)
at NgModuleRef_.get (refs.js:1037)
at resolveDep (provider.js:455)
at _NullInjector.get (injector.js:31)
at resolveToken (injector.js:387)
at tryResolveToken (injector.js:330)
at StaticInjector.get (injector.js:170)
at resolveToken (injector.js:387)
at tryResolveToken (injector.js:330)
at StaticInjector.get (injector.js:170)
at resolveNgModuleDep (ng_module.js:103)
at NgModuleRef_.get (refs.js:1037)
at resolveDep (provider.js:455)
at resolvePromise (zone.js:824)
at resolvePromise (zone.js:795)
at zone.js:873
at ZoneDelegate.invokeTask (zone.js:425)
at Object.onInvokeTask (ng_zone.js:575)
at ZoneDelegate.invokeTask (zone.js:424)
at Zone.runTask (zone.js:192)
at drainMicroTaskQueue (zone.js:602)
at ZoneTask.invokeTask [as invoke] (zone.js:503)
at invokeTask (zone.js:1540)
defaultErrorLogger @ errors.js:48
ErrorHandler.handleError @ error_handler.js:90
next @ application_ref.js:311
schedulerFn @ event_emitter.js:156
SafeSubscriber.__tryOrUnsub @ Subscriber.ts:254
SafeSubscriber.next @ Subscriber.ts:204
Subscriber._next @ Subscriber.ts:135
Subscriber.next @ Subscriber.ts:95
Subject.next @ Subject.ts:61
EventEmitter.emit @ event_emitter.js:131
(anonymous) @ ng_zone.js:605
ZoneDelegate.invoke @ zone.js:392
Zone.run @ zone.js:142
NgZone.runOutsideAngular @ ng_zone.js:404
onHandleError @ ng_zone.js:605
ZoneDelegate.handleError @ zone.js:396
Zone.runGuarded @ zone.js:158
_loop_1 @ zone.js:702
api.microtaskDrainDone @ zone.js:711
drainMicroTaskQueue @ zone.js:610
ZoneTask.invokeTask @ zone.js:503
invokeTask @ zone.js:1540
globalZoneAwareCallback @ zone.js:1566
mes app.module.ts: -
import { NgModule, Injectable } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { RouterModule, Routes } from '@angular/router';
import { HttpModule } from '@angular/http';
import { ModalModule } from 'ngx-modialog';
import { BootstrapModalModule, Modal, bootstrap4Mode } from 'ngx-modialog/plugins/bootstrap';
import { AppComponent } from './app.component';
import { ExportToPdfComponent } from './exportTopdf/exportTopdf.component';
import { InvalidPageComponent } from './invalidPage/invalidPage.component';
import { ViewCountService } from './Service/viewsCount.component';
const appRoutes: Routes = [
{ path: 'home', component: AppComponent },
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'export', component: ExportToPdfComponent },
{ path: '**', component: InvalidPageComponent }
];
@NgModule({
imports: [
BrowserModule,
HttpModule,
RouterModule.forRoot(appRoutes),
ModalModule.forRoot(),
BootstrapModalModule
],
declarations: [
AppComponent,
ExportToPdfComponent,
InvalidPageComponent
],
bootstrap: [
AppComponent
],
providers: [
ViewCountService
]
})
export class AppModule { }
fichier exportTopdf.component.ts: -
import { Component, ViewContainerRef, ViewEncapsulation } from '@angular/core';
import { ViewCountService } from '../Service/ViewsCount.component';
import { Overlay } from 'ngx-modialog';
import { Modal } from 'ngx-modialog/plugins/bootstrap';
@Component({
selector: 'export-to-pdf',
templateUrl: 'app/exportTopdf/exportTopdf.component.html',
})
export class ExportToPdfComponent {
name: string;
fields: any;
constructor(public modal: Modal, private ViewCountService: ViewCountService) {
debugger;
this.fields = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
}
getViewCount(): void {
debugger;
this.ViewCountService.getViewCount()
.then(data => {
this.name = data;
console.log("I CANT SEE DATA HERE: ", this.name)
});
}
}
mon code de service: -
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Rx';
@Injectable()
export class ViewCountService {
constructor(private http: Http) {
}
getViewCount() {
return this.http.get('api/Tableau/GetViewsCount')
.map(response => response.json() as string).toPromise();
}
getDataObservable(url: string) {
return this.http.get('api/Tableau/GetViewsCount')
.map(data => {
data.json();
console.log("I CAN SEE DATA HERE: ", data.json());
});
}
}
system.config.js: -
/**
* System configuration for Angular samples
* Adjust as necessary for your application needs.
*/
(function (global) {
System.config({
transpiler: 'TypeScript',
//TypeScript compiler options
typescriptOptions: {
emitDecoratorMetadata: true
},
paths: {
// paths serve as alias
'npm:': '/node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
'app': 'app',
// angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
// other libraries
'rxjs': 'npm:rxjs',
'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
'ngx-modialog': 'npm:ngx-modialog/bundle/ngx-modialog.umd.min.js',
'ngx-modialog/plugins/bootstrap': 'npm:ngx-modialog/plugins/bootstrap/bundle/ngx-modialog-bootstrap.umd.min.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
defaultExtension: 'js',
meta: {
'./*.js': {
loader: 'systemjs-angular-loader.js'
}
}
},
rxjs: {
defaultExtension: 'js'
}
}
});
})(this);
package.json: -
{
"name": "angular-quickstart",
"version": "1.0.0",
"description": "QuickStart package.json from the documentation, supplemented with testing support",
"scripts": {
"build": "tsc -p src/",
"build:watch": "tsc -p src/ -w",
"build:e2e": "tsc -p e2e/",
"serve": "lite-server -c=bs-config.json",
"serve:e2e": "lite-server -c=bs-config.e2e.json",
"prestart": "npm run build",
"start": "concurrently \"npm run build:watch\" \"npm run serve\"",
"pree2e": "npm run build:e2e",
"e2e": "concurrently \"npm run serve:e2e\" \"npm run protractor\" --kill-others --success first",
"preprotractor": "webdriver-manager update",
"protractor": "protractor protractor.config.js",
"pretest": "npm run build",
"test": "concurrently \"npm run build:watch\" \"karma start karma.conf.js\"",
"pretest:once": "npm run build",
"test:once": "karma start karma.conf.js --single-run",
"lint": "tslint ./src/**/*.ts -t verbose"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"@angular/common": "~5.0.3",
"@angular/compiler": "~5.0.3",
"@angular/core": "~5.0.3",
"@angular/forms": "~5.0.3",
"@angular/http": "~5.0.3",
"@angular/platform-browser": "~5.0.3",
"@angular/platform-browser-dynamic": "~5.0.3",
"@angular/router": "~5.0.3",
"angular-in-memory-web-api": "~0.5.1",
"bootstrap": "^3.3.7",
"core-js": "^2.4.1",
"ngx-modialog": "^5.0.0",
"rxjs": "5.5.2",
"systemjs": "0.20.19",
"zone.js": "^0.8.4"
},
"devDependencies": {
"concurrently": "^3.2.0",
"lite-server": "^2.2.2",
"TypeScript": "~2.6.1",
"canonical-path": "0.0.2",
"tslint": "^5.8.0",
"lodash": "^4.16.4",
"jasmine-core": "~2.8.0",
"karma": "^1.3.0",
"karma-chrome-launcher": "^2.0.0",
"karma-cli": "^1.0.1",
"karma-jasmine": "^1.0.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.2.0",
"rimraf": "^2.5.4",
"@types/node": "^8.0.53",
"@types/jasmine": "2.8.2"
},
"repository": {}
}
Merci d’avance pour vos précieux commentaires et réactions.
Si vous utilisez Angular 4.3+ jusqu'à 5, vous devrez importer HttpClient dans votre app.module depuis la nouvelle bibliothèque.
> import { HttpClientModule } from '@angular/common/http';
imports: [
YModule,
XModule,
HttpClientModule
],
A votre service:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Rx';
@Injectable()
export class ViewCountService {
constructor(private http: HttpClient ) {
}
getViewCount() {
return this.http.get('api/Tableau/GetViewsCount');
}
...
}
Dans votre composant:
getViewCount(): void {
this.ViewCountService.getViewCount()
.subscribe(
data =>{console.log(data);//your data},
err=>{console.log(err);},
() => {console.log("Done loading");}
);
}
Regarde tes impors
app.module.ts
import { ViewCountService } from './Service/viewsCount.component';
exportTopdf.component.ts
import { ViewCountService } from '../Service/ViewsCount.component';
Puisque Systemjs
est sensible à la casse (voir L'instance de service n'est pas disponible pour le composant enfant dans angular2 })
on dirait que vous importez différents modules
ViewsCount
|
viewsCount
Alors, choisissez une seule option pour importer votre service
app.module.ts
import { ViewCountService } from './Service/viewsCount.component';
exportTopdf.component.ts
import { ViewCountService } from '../Service/viewsCount.component';
^
instead of V
Lisez aussi style guide _ pour mieux comprendre comment nommer vos fichiers.
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
routing
],
ajoutez ceci dans votre app.module.ts fichier
Je faisais face au même problème alors j'ai ajouté la ligne ci-dessous dans app.module et cela a fonctionné pour moi.
import { HttpClientModule } from ‘@angular/common/http’;
Et l'ajouter à la
@NgModule({ imports: [ ..., HttpClientModule,... ]
Cela ne semble pas encore résolu: https://github.com/angular/angular/issues/20339
En guise de solution de contournement, essayez de rendre toutes vos fonctions constructor()
sans paramètres en extrayant les propriétés en tant que.
ExportToPdfComponent:
import { Component, ViewContainerRef, ViewEncapsulation } from '@angular/core';
import { ViewCountService } from '../Service/ViewsCount.component';
import { Overlay } from 'ngx-modialog';
import { Modal } from 'ngx-modialog/plugins/bootstrap';
@Component({
selector: 'export-to-pdf',
templateUrl: 'app/exportTopdf/exportTopdf.component.html',
})
export class ExportToPdfComponent {
name: string;
fields: any;
modal: Modal;
ViewCountService: ViewCountService;
constructor() {
debugger;
this.fields = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }];
}
getViewCount(): void {
debugger;
this.ViewCountService.getViewCount()
.then(data => {
this.name = data;
console.log("I CANT SEE DATA HERE: ", this.name)
});
}
}
ViewCountService:
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Rx';
@Injectable()
export class ViewCountService {
private http: Http;
constructor() {
}
getViewCount() {
return this.http.get('api/Tableau/GetViewsCount')
.map(response => response.json() as string).toPromise();
}
getDataObservable(url: string) {
return this.http.get('api/Tableau/GetViewsCount')
.map(data => {
data.json();
console.log("I CAN SEE DATA HERE: ", data.json());
});
}
}