4

I am trying to do file upload in Angular 2. Trying

let file:FileList = inputEl.files[0];
console.log(file);
    this.http.post(url, file)
         .map(res => {
              return  res.headers.get("content-type");
            })
            .catch(err => {
             return Observable.throw(err);
            })
            .subscribe((res) => { // <-- this function
                console.log(res)
            });

I can see the POST call happening now. But I still am not able to see the file upload happening, How exactly the File Upload request should look like.

9
  • Have you actually .subscribed to the POST? Commented Oct 22, 2016 at 11:45
  • @jonrsharpe Actually new to angular 2. Was able to do simple form submit but not able to wrap my mind around how to do a file upload, also not sure of the structure in my java code for file upload Commented Oct 22, 2016 at 11:48
  • ...that doesn't answer my question. Could you give a minimal reproducible example? What comes after .post(...)? Commented Oct 22, 2016 at 11:48
  • 1
    Well that might be the problem; you have to subscribe to observables to make them do anything. I'd suggest looking at the tutorials for Angular 2 http. Commented Oct 22, 2016 at 11:56
  • 1
    Observables are lazy and are only executed when callbacks are subscribed to them. Commented Oct 22, 2016 at 13:03

4 Answers 4

3

your http service file:

import { Injectable } from "@angular/core";
import { ActivatedRoute, Router } from '@angular/router';
import { Http, Headers, Response, Request, RequestMethod, URLSearchParams, RequestOptions } from "@angular/http";
import {Observable} from 'rxjs/Rx';
import { Constants } from './constants';
declare var $: any;

@Injectable()
export class HttpClient {
  requestUrl: string;
  responseData: any;
  handleError: any;

  constructor(private router: Router, 
  private http: Http, 
  private constants: Constants, 
  ) {
    this.http = http;
  }

  postWithFile (url: string, postData: any, files: File[]) {

    let headers = new Headers();
    let formData:FormData = new FormData();
    formData.append('files', files[0], files[0].name);
    // For multiple files
    // for (let i = 0; i < files.length; i++) {
    //     formData.append(`files[]`, files[i], files[i].name);
    // }

    if(postData !=="" && postData !== undefined && postData !==null){
      for (var property in postData) {
          if (postData.hasOwnProperty(property)) {
              formData.append(property, postData[property]);
          }
      }
    }
    var returnReponse = new Promise((resolve, reject) => {
      this.http.post(this.constants.root_dir + url, formData, {
        headers: headers
      }).subscribe(
          res => {
            this.responseData = res.json();
            resolve(this.responseData);
          },
          error => {
            this.router.navigate(['/login']);
            reject(error);
          }
      );
    });
    return returnReponse;
  }
}

call your function (Component file):

onChange(event) {
    let file = event.srcElement.files;
    let postData = {field1:"field1", field2:"field2"}; // Put your form data variable. This is only example.
    this._service.postWithFile(this.baseUrl + "add-update",postData,file).then(result => {
        console.log(result);
    });
}

your html code:

<input type="file" class="form-control" name="documents" (change)="onChange($event)" [(ngModel)]="stock.documents" #documents="ngModel">

your server file (Like PHP):

print_r($_FILES);
Sign up to request clarification or add additional context in comments.

Comments

1

Http requests are only sent when you subscribe to them.

this._http.post("url", "file")
         .map(res => {
              return  res.headers.get("content-type");
            })
            .catch(err => {
             return Observable.throw(err);
            })
            .subscribe((res) => { // <-- this function
                console.log(res)
            })

You can find more about creating http client with Angular 2 here.

2 Comments

thanks i can see the POST call happening now, But i still am not able to see the file Upload happening can you help me with figuring how exactly should my POST call look like, I want to upload a file along with some of its MetaData.
I haven't done a file upload by myself yet, so i don't have a clear idea about how it should look. This looks like a full example. Check it out: stackoverflow.com/questions/32423348/…
0
1. remember when you are submitting form data with file , header should be blanked 


        let headers = new Headers();  

        let options       = new RequestOptions({ headers: headers });  

2. Rest You can follow from upper example @Bharat Chauhan

3. i tested with all others headers , but it worked if its leave blanked ! 


Step 1.   <input type="file" (change)="fileChangeEvent($event)" placeholder="Upload file..." />  

Step 2. 
 fileChangeEvent(e:any):void{





 let commentOperation:Observable<any>;

 let fileList: FileList = e.target.files;
 let file: File = fileList[0];
        let formData:FormData = new FormData();
        formData.append('file', file, file.name);

 commentOperation = this.test1Service_.submitComment( formData);
  commentOperation.subscribe(
                                fileUpload => {

                                  console.log(fileUpload)
                                }, 
                                err => {
                                    // Log errors if any
                                    console.log(err);
                                }
                                );



 }

Step 3: 

  submitComment (body: any): Observable<any> {



        let headers = new Headers();



        let options       = new RequestOptions({ headers: headers });  

        return this.http.post(this.commentsUrl,body , options) // ...using post request
                         .map((res:Response) => res.json()) // ...and calling .json() on the response to return data
                         .catch((error:any) => Observable.throw(error.json().error || 'Server error')); //...errors if any
    }


Step 4: PHP : 



header('Access-Control-Allow-Origin: *');





if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
  echo json_encode(array('status' => false));
  exit;
}

$path = 'uploads/';

if (isset($_FILES['file'])) {
  $originalName = $_FILES['file']['name'];
  $ext = '.'.pathinfo($originalName, PATHINFO_EXTENSION);
  $generatedName = md5($_FILES['file']['tmp_name']).$ext;
  $filePath = $path.$generatedName;

  if (!is_writable($path)) {
    echo json_encode(array(
      'status' => false,
      'msg'    => 'Destination directory not writable.'
    ));
    exit;
  }

  if (move_uploaded_file($_FILES['file']['tmp_name'], $filePath)) {
    echo json_encode(array(
      'status'        => true,
      'originalName'  => $originalName,
      'generatedName' => $generatedName
    ));
  }
}
else {
  echo json_encode(
    array('status' => false, 'msg' => 'No file uploaded.')
  );
  exit;
}

Comments

0

fileChange(event) {

let fileList: FileList = event.srcElement.files;
if(fileList.length > 0) {
    let file: File = fileList[0];
    let formData:FormData = new FormData();
    formData.append('uploadFile', file, file.name);
    let headers = new Headers();
    headers.append('enctype', 'multipart/form-data');
    headers.append('Accept', 'application/json');
    let options = new RequestOptions({ headers: headers });
    this.http.post(`${this.apiEndPoint}`, formData, options)
        .map(res => res.json())
        .catch(error => Observable.throw(error))
        .subscribe(
            data => console.log('success'),
            error => console.log(error)
        )
}

}

I took reference from : File Upload In Angular 2? But got it working after changing 'Content-Type' to 'enctype' and 'event.target.files' to 'event.srcElement.files'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.