This is my Angular configuration :
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
My package.json file :
{
"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"
}
}
I obtain this error message when i run the command '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)
This is my 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);
...
});
After analyze and debug, the problem comes from the call of the "login" method of the User Service.
Having browsed of numerous post (and solutions) i do not understand the real origin of my error message.
This is my User Service :
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);
}
Any ideas ?
For me, this issue came from trying to include HttpClient
and HttpHandler
in my providers like so:
providers: [
HttpClient,
HttpHandler
]
This kept throwing errors along the lines of _TypeError: this.handle.handler is not a function
To fix this, I found I could remove HttpClient
and HttpHandler
from the providers and instead add HttpClientTestingModule
to my imports like so:
imports: [
HttpClientTestingModule
]
This solved this particular error for me in my Karma unit tests for Angular 7.
Please add error handler in your component.ts where you are calling this login(credentials) method.
user_login() {
this.userService.login(credentials).subscribe((res) => {
console.log(res);
}, (error) => {
console.log(error);
});
I ran across this problem while attempting to convert my tests to use HttpTestingController
. I believe the accepted answer simply suppresses the problem and prints it to the console. There is a lot that I still do not understand for my solution below, but hopefully it can help someone.
The problem in my application was that I was providing HttpHandler
in my providers
list. This was causing _this.handler
to be an HttpHandler
at the offending line in http.js
, in the stack trace.
var /** @type {?} */ events$ = concatMap.call(of(req), function (req) { return _this.handler.handle(req); });
I removed HttpHandler
from the providers in my TestBed.configureTestModule
and then _this.handler
was an HttpInterceptorHandler
which had the appropriate handle
function.
The verified 'answer' is actually catching the error instead of fixing it.
As found in this answer, you need to replace your imports:
import {HttpClient, HttpHandler} from '@angular/common/http';
with
import {HttpClientModule} from '@angular/common/http';
Also replace TestBed testing module's providers:
imports: [],
providers: [HttpClient, HttpHandler]
with:
imports: [HttpClientModule],
providers: []
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With