1

I'm trying to implement an http interceptor that will update a progress bar each time a http request is sent to the API (also if report progress is true). In the very basic stage of it, which is why everything is mostly console logs and comments.

The problem I'm having is the event.total is undefined for every API call that I make, even if I look in the network tab and can see that the response headers have a content-length that is returns. What am I doing wrong here?

Is the networks Content-Length headers different than what Angular sees? I console logged the events response headers and there is no Content-Length inside of there, not sure if those are two different things though.

Interceptor code:

intercept( request: HttpRequest<unknown>, next: HttpHandler ): Observable<HttpEvent<unknown>> {
    if ( request.reportProgress ) {
      return next.handle( request ).pipe(
        tap( ( event: HttpEvent<any> ) => {
          if ( event.type === HttpEventType.DownloadProgress ) {
            //update progress bar
            console.log( event.loaded );
            console.log( event.total );
            console.log( Math.round( event.loaded / event.total * 100 ) );
          } else if ( event.type === HttpEventType.Response ) {
            //hide progress bar
            console.log( event.headers );
          }
        }, error => {
          //hide progress bar, show error notification here or http error interceptor?
          console.log( error );
        } )
      )
    }
    return next.handle( request );
  }

Screenshot of network logs: Screenshot of network logs

Screenshot of console logs: Screenshot of network logs

Thank you for your help!

Edit: Example of API call as requested:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { PlatformTheme } from 'src/app/models/platform-theme/platform-theme.model';
import { environment } from 'src/environments/environment';
import { SessionService } from '../session/session.service';

@Injectable( {
  providedIn: 'root'
} )
export class ThemeService {

  constructor( private _httpClient: HttpClient, private _session: SessionService ) { }

  getPlatformThemes( platformType: string ): Observable<PlatformTheme> {
    return this._httpClient.get( `${environment.apiBaseUrl}/v1/Places/${this._session.placeId}/Platform/${platformType}/Theme`, { reportProgress: true } )
      .pipe( map( ( response: PlatformTheme ) => new PlatformTheme( response ) ) )
  }

}
M.Chappell
  • 43
  • 2
  • 9

1 Answers1

0

Event.total is a optional field and might not be available or computable. Refer here:-

https://angular.io/api/common/http/HttpProgressEvent

For the Content-Length header issue that is not exposed by your backend to be accessed on UI. For that you need to send it in Access-Control-Expose-Headers in response. Refer :-

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers

Aakash Garg
  • 10,649
  • 2
  • 7
  • 25
  • Content-Length is a whitelisted header that does not need to be specified in Access-Control-Expose-Headers. – UniversE Feb 22 '23 at 18:33