0

I need to show a progress-bar when uploading files. After much plagiarising the net, started with the following:

TL;DR

ProgressService is not being injected in CustomBrowserXhr.

The long version:

Extended BrowserXhr

import { ProgressService } from "./progress-service";

@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
  constructor(private service:ProgressService) {
    super();
  }

   build(): any {
     let xhr = super.build();

      xhr.onprogress = (event) => {            
        this.service.downloadProgress.next(event);
      };

      xhr.upload.onprogress = (event) => {      
        this.service.uploadProgress.next(event);
      };

      return <any>(xhr);
  }
}

The Progress Service

@Injectable()
export class ProgressService {

  downloadProgress: Subject<any> = new Subject();
  uploadProgress: Subject<any> = new Subject();

}

Bootstraping (Elided for brevity)

import { BrowserXhr }               from "@angular/http";
import { CustomBrowserXhr }         from "./services/custom-browser-xhr";
import { ProgressService }          from "./services/progress-service";

@NgModule({
    imports: [ 
       BrowserModule, 
       HttpModule, 
       FormsModule,
       Ng2Bs3ModalModule
    ],
    declarations: [ ],
    providers: [
        ProgressService,
        { provide: BrowserXhr, useClass: CustomBrowserXhr }
    ],
    bootstrap: [ 
        ApplicationComponent        
    ]
})
export class AppModule { }

The issue is, ProgressSerice is not injected in CustomBrowserXhr. Getting the following error:

Uncaught TypeError: Cannot read property 'downloadProgress' of undefined
    at XMLHttpRequest.xhr.onprogress (custom-browser-xhr.ts:16)
    at XMLHttpRequest.wrapFn [as _onprogress] (zone.js:1039)
    at ZoneDelegate.invokeTask (zone.js:275)
    at Object.onInvokeTask (core.umd.min.js:35)
    at ZoneDelegate.invokeTask (zone.js:274)
    at Zone.runTask (zone.js:151)
    at XMLHttpRequest.ZoneTask.invoke (zone.js:345)
xhr.onprogress @ custom-browser-xhr.ts:16
wrapFn @ zone.js:1039
ZoneDelegate.invokeTask @ zone.js:275
onInvokeTask @ core.umd.min.js:35
ZoneDelegate.invokeTask @ zone.js:274
Zone.runTask @ zone.js:151
ZoneTask.invoke @ zone.js:345
resume-service.ts:21 s

Put a break-point on the following line and indeed found service to be null:

this.service.downloadProgress.next(event);
kmansoor
  • 4,265
  • 9
  • 52
  • 95
  • I think the code looks fine. I assume you have omitted `BrowserModule, HttpModule` in `imports` fore brevity. – Günter Zöchbauer Feb 22 '17 at 06:21
  • @GünterZöchbauer, I have updated the question to show I do include the modules you mentioned, can you please take a look and see if I missed something? Thanks. – kmansoor Feb 22 '17 at 14:44
  • Can't find anything wrong. Quite weird. – Günter Zöchbauer Feb 22 '17 at 14:48
  • 1
    I was able to get this working. [See here.](http://stackoverflow.com/questions/39657765/angular-2-0-how-to-extend-browserxhr-to-create-progress-bar/42841638#42841638) Now I want to create a service that also calculates the upload time remaining. – wolfhoundjesse Mar 22 '17 at 14:21

0 Answers0