C'est ma configuration angulaire:
Angular CLI: 1.7.2
Node: 6.10.0
OS: win32 x64
Angular: 5.2.5
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
@angular/cli: 1.7.2
@angular-devkit/build-optimizer: 0.3.2
@angular-devkit/core: 0.3.2
@angular-devkit/schematics: 0.3.2
@ngtools/json-schema: 1.2.0
@ngtools/webpack: 1.10.1
@schematics/angular: 0.3.2
@schematics/package-update: 0.3.2
TypeScript: 2.6.2
webpack: 3.11.0
Mon fichier package.json:
{
"name": "xxxx",
"version": "0.0.0",
"license": "MIT",
"scripts": {
"ng": "ng",
"start": "ng serve --proxy-config proxy.conf.json",
"build": "ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"ng2ninja": "ng2ninja"
},
"private": true,
"dependencies": {
"@angular/animations": "5.2.5",
"@angular/common": "5.2.5",
"@angular/compiler": "5.2.5",
"@angular/core": "5.2.5",
"@angular/forms": "5.2.5",
"@angular/platform-browser": "5.2.5",
"@angular/platform-browser-dynamic": "5.2.5",
"@angular/router": "5.2.5",
"@ng-bootstrap/ng-bootstrap": "^1.0.0",
"bootstrap": "4.0.0",
"core-js": "2.4.1",
"font-awesome": "4.7.0",
"rxjs": "5.5.6",
"tslint-sonarts": "^1.6.0",
"yarn": "^1.5.1",
"zone.js": "0.8.19"
},
"devDependencies": {
"@angular/cli": "^1.7.1",
"@angular/compiler-cli": "5.2.5",
"@angular/language-service": "5.2.5",
"@types/jasmine": "2.8.6",
"@types/jasminewd2": "2.0.3",
"@types/node": "8.5.2",
"@ng-bootstrap/ng-bootstrap": "1.0.0",
"angular-ide": "^0.9.39",
"codelyzer": "4.1.0",
"jasmine-core": "2.8.0",
"jasmine-spec-reporter": "4.2.1",
"karma": "2.0.0",
"karma-chrome-launcher": "2.2.0",
"karma-coverage-istanbul-reporter": "1.3.3",
"karma-firefox-launcher": "1.1.0",
"karma-jasmine": "1.1.1",
"karma-jasmine-html-reporter": "0.2.2",
"karma-json-reporter": "1.2.1",
"ng2ninja": "1.0.17",
"protractor": "5.2.2",
"ts-node": "4.1.0",
"tslint": "5.9.1",
"TypeScript": "2.6.2"
}
}
J'obtiens ce message d'erreur lorsque j'exécute la commande 'ng test' :
TypeError: this.handler.handle is not a function
at MergeMapSubscriber.__WEBPACK_IMPORTED_MODULE_2_rxjs_operator_concatMap__.a.call [as project] node_modules/@angular/common/esm2015/http.js:1174:28)
at MergeMapSubscriber._tryNext node_modules/rxjs/_esm2015/operators/mergeMap.js:109:1)
at MergeMapSubscriber._next node_modules/rxjs/_esm2015/operators/mergeMap.js:99:1)
at MergeMapSubscriber.next node_modules/rxjs/_esm2015/Subscriber.js:83:1)
at ScalarObservable._subscribe node_modules/rxjs/_esm2015/observable/ScalarObservable.js:42:1)
at ScalarObservable._trySubscribe node_modules/rxjs/_esm2015/Observable.js:171:1)
at ScalarObservable.subscribe node_modules/rxjs/_esm2015/Observable.js:159:1)
at MergeMapOperator.call node_modules/rxjs/_esm2015/operators/mergeMap.js:78:1)
at Observable.subscribe node_modules/rxjs/_esm2015/Observable.js:156:1)
Ceci est mon test:
import {TestBed, inject} from '@angular/core/testing';
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
import {UserService} from './user.service';
import {environment} from '../environments/environment';
import {JwtInterceptorService} from './jwt-interceptor.service';
import {User} from './services/model/user';
import {HttpClient, HttpHandler} from '@angular/common/http';
...
it('should authenticate a user', () => {
// spy on the store method
spyOn(userService, 'storeLoggedInUser');
const credentials = {login: 'toto', password: 'titi'};
let actualUser;
userService.login(credentials).subscribe(fetchedUser => actualUser = fetchedUser);
...
});
Après analyse et débogage, le problème provient de l’appel de la méthode "login" du service utilisateur.
Après avoir parcouru de nombreux articles (et solutions), je ne comprends pas la véritable origine de mon message d'erreur.
Ceci est mon service utilisateur:
login(credentials): Observable<User> {
var headers = new HttpHeaders();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
var paramCredentials = "grant_type=password"
+ "&credentials=true"
+ "&scope=read write"
+ "&accept=application/json"
+ "&username=" + credentials.username
+ "&password=" + credentials.password;
return this.http.post<User>(`${environment.oAuthUrl}/oauth/token`, paramCredentials, {headers: headers}).pipe(
tap(user => this.storeLoggedInUser(user))
);
}
storeLoggedInUser(user) {
window.localStorage.setItem('jwtToken', JSON.stringify(user));
this.jwtInterceptorService.setJwtToken(user.token);
}
Des idées ?
Merci d'avance
Veuillez ajouter un gestionnaire d'erreurs dans votre composant.ts où vous appelez cette méthode Login (informations d'identification).
user_login() {
this.userService.login(credentials).subscribe((res) => {
console.log(res);
}, (error) => {
console.log(error);
});
J'ai rencontré ce problème en essayant de convertir mes tests pour utiliser HttpTestingController
. Je crois que la réponse acceptée supprime simplement le problème et l’imprime sur la console. Il y a beaucoup de choses que je ne comprends toujours pas pour ma solution ci-dessous, mais j'espère que cela pourra aider quelqu'un.
Le problème dans ma candidature était que je fournissais HttpHandler
dans ma liste providers
. Cela causait _this.handler
d'être une HttpHandler
sur la ligne incriminée dans http.js
, dans la trace de la pile.
var /** @type {?} */ events$ = concatMap.call(of(req), function (req) { return _this.handler.handle(req); });
J'ai supprimé HttpHandler
des fournisseurs dans mon TestBed.configureTestModule
et _this.handler
était alors une HttpInterceptorHandler
dotée de la fonction handle
appropriée.
Probablement que vous n'utilisez pas HttpHandler et Angular ne peuvent pas trouver cela.
Essayez de supprimer HttpHandler de "importer" et "fournisseurs" dans votre app.module.ts:
import {HttpClient} from '@angular/common/http';
...
providers: [HttpClient],