Search code examples
angulartypescriptrxjsangular-http-interceptors

Cannot read property 'length' of null on Angular Service method call?


I'm modifying an existing Angular project (not mine), adding a new call to my external API.

This is the service method:

getUserName(): Observable<any> {
    return this.http.get<any>(environment.apiUrl + URLS.USER_NAME)
}

And I use it on appcomponent.ts as following:

this.userService.getUserName().subscribe((name) => { 
  this.user = name
})

When executing I get the following error:

core.js:1673 ERROR TypeError: Cannot read property 'length' of null at HttpHeaders.push../node_modules/@angular/common/fesm5/http.js.HttpHeaders.applyUpdate (http.js:199) at http.js:170 at Array.forEach () at HttpHeaders.push../node_modules/@angular/common/fesm5/http.js.HttpHeaders.init (http.js:170) at HttpHeaders.push../node_modules/@angular/common/fesm5/http.js.HttpHeaders.forEach (http.js:235) at Observable._subscribe (http.js:1435) at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (Observable.js:43) at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:29) at MapOperator.push../node_modules/rxjs/_esm5/internal/operators/map.js.MapOperator.call (map.js:18) at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:24)

It seems to be a headers problem or some subscribe/observable error, but I can't find where the error is.

  • Is there something wrong with my code?
  • It could be an existing interceptor that is modifying the request?

Note that the exception is thrown before making the request, so it must be a client problem when creating that request.

Edit:

This is the only interceptor I found:

@Injectable({
  providedIn: 'root'
})
export class TenantHttpInterceptor implements HttpInterceptor {

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (req.url.indexOf(environment.apiTFSmin) === -1) {
      let tenantReq = req.clone({ headers: req.headers.set('current', sessionStorage.getItem('current')) })
      if (sessionStorage.getItem('tenant') != null && sessionStorage.getItem('newTenant') == null) {
        tenantReq = tenantReq.clone({ headers: tenantReq.headers.append('Tenant', sessionStorage.getItem('tenant')) })
      } else if (sessionStorage.getItem('newTenant') != null) {
        tenantReq = tenantReq.clone({ headers: tenantReq.headers.append('Tenant', sessionStorage.getItem('newTenant')) })
        sessionStorage.removeItem('newTenant')
      }
      if (req.method === 'POST' || req.method === 'PUT') {
        tenantReq = tenantReq.clone({ headers: tenantReq.headers.append('Content-Type', 'application/json') })
      }
      return next.handle(tenantReq)
    } else {
      const tenantReq = req.clone({ headers: req.headers.set('Authorization', 'Bearer ' + btoa('pescanilla-ext:m12345678*')) })
      // const tenantReq = req.clone()
      return next.handle(tenantReq)
    }
  }
}

Solution

  • You are not checking the 'current' header to actually exist in the storage.

    let tenantReq = req.clone({ headers: req.headers.set('current', sessionStorage.getItem('current')) })
    

    Edit: The HttpClient will throw an error once you try to send a request with header with null value. Try replacing the sessionStorage.getItem('current') with a static value and test it.