angular - Få serversvaret etter xhr.send() i en Observable


Jeg implementerte en metode for å POSTE en fil i min Angular 2-app. Den er basert på løsningen jeg fant her.

Siden Angular 2 ikke støtter filopplasting av seg selv, må løsningen bruke xhr. Slik ser den fungerende løsningen ut:

Komponentmetoden:

onSubmit(): void {
    this.inputModuleService.postFile(this.files).subscribe(() => {
        console.log('sent');
    });
}

Tjenestemetoden:

postFile (files: File[]): Observable<string> {
    var url = this.uploadURL;

    return Observable.create(observer => {
        var formData: FormData = new FormData()
        var xhr: XMLHttpRequest = new XMLHttpRequest();

        formData.append("upload", files[i], files[i].name);

        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    observer.next(JSON.parse(xhr.response));
                    observer.complete();
                } else {
                observer.error(xhr.response);
                }
            }
        };

        xhr.open('POST', url, true);
        xhr.send(formData);
    });
}

Mitt problem er at jeg ikke forstår hvordan jeg skal få responsen tilbake til onSubmit()-metoden etter kall til xhr.send(). Angular2 og konseptet med observables og promises er helt nytt for meg.

Hvordan kan jeg få serverens svar fra dette observable?

Svar #1

Serverens respons gis til suksess- og feilkallbackene til subscribe():

onSubmit(): void {
    this.inputModuleService.postFile(this.files).subscribe(
      response => {
          //response is the server's response, parsed into a javascript object
          console.log('server responded: ', response);
      },
      error => {
          //server response emitted when xhr.status !== 200
          console.error(error);
      }
   );
}

Denne linjen:

formData.append("upload", files[i], files[i].name);

Vil kaste feil fordi i er udefinert. Koden du kopierte fra hadde den linjen innenfor en løkke, og i var den nåværende indeksen. Det er ikke tilfelle i koden din.

Funksjonsdeklarasjonen din:

postFile (files: File[]): Observable<string>

Bør endres til

postFile (files: File[]): Observable<any>

Fordi Observable som returneres av postFile sender ut objekter, ikke strenger.

Hvis du mener å laste opp bare én fil, bør du også endre files: File[] til file: File og legge til filen med:

formData.append("upload", file, file.name);