15

I am using ng2-file-upload in angular 2. Is there any way to submit my form data with file upload action?

Ghanshyam
  • 265
  • 1
  • 2
  • 11
  • Could you please give a more detailed explanation on what exactly you're wanting to do? I've worked with that package so I may be able to help, I'm just struggling to understand what you're trying to achieve – Wesley Coetzee Jul 21 '16 at 11:29
  • I am creating one user form using form builder. User form has firstname, lastname, email, profile_imag, status etc fields. How to post all of user input data (firstname, lastname, email etc...) with profile_image data using one server call. I am using laravel as a backend, – Ghanshyam Jul 21 '16 at 12:37
  • If you look inside the example, they have `item.upload()`, that `item` has a property on it called `item.formData`, I THINK you can add your formdata on that via `item.formData=yourFormData`. I haven't used the package in this way. – Wesley Coetzee Jul 22 '16 at 06:30
  • @Ghanshyam Could you explain how to use ng2-file-upload with PHP? I trying to find something on internet, but nothing until now. Thanks in advance. – Vitor Oct 16 '16 at 01:30
  • I have applied below methods for submit file upload data with form data (Posted answer: Jane Wayne) – Ghanshyam Oct 27 '16 at 08:38

3 Answers3

31

I was having the same problem using ng2-file-upload. They have a hook called onBeforeUploadItem. The following did not work:

ngOnInit() {
 this.uploader.onBeforeUploadItem = (fileItem: any) => {
  fileItem.formData.push( { someField: this.someValue } );
  fileItem.formData.push( { someField2: this.someValue2 } );
 };
}

When I logged out the content of fileItem.formData all the values are there. However, these form elements seem to never make it back to the server. I am using Chrome and when I observe the HTTP post, I saw the following:

Request Headers

POST /api/upload/csv HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 228
Origin: http://localhost:4200
x-access-token: eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJyb290IiwiYWRkciI6IjA6MDowOjA6MDowOjA6MSIsInNjaGVtZSI6Imh0dHAiLCJwb3J0IjoiODA4MCIsImlhdCI6MTQ2OTUwMzM1NX0.jICVQdZD-6m705sZsaQJ5-51LztdIx9pAAKgVYgL3HRMMgrJh6ldFbYvUVtA_UQkSrvCrNJeWeo4C7QYe2W4Cw
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryCSUTihSBrgmwjxg1
Accept: */*
Referer: http://localhost:4200/main
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: _ga=GA1.1.941072201.1467616449; token=eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJyb290IiwiYWRkciI6IjA6MDowOjA6MDowOjA6MSIsInNjaGVtZSI6Imh0dHAiLCJwb3J0IjoiODA4MCIsImlhdCI6MTQ2OTUwMzM1NX0.jICVQdZD-6m705sZsaQJ5-51LztdIx9pAAKgVYgL3HRMMgrJh6ldFbYvUVtA_UQkSrvCrNJeWeo4C7QYe2W4Cw

Request Payload

------WebKitFormBoundaryCSUTihSBrgmwjxg1
Content-Disposition: form-data; name="file"; filename="data.csv"
Content-Type: text/csv


------WebKitFormBoundaryCSUTihSBrgmwjxg1--

The actual solution

It turns out I was pretty close. The solution was to override onBuildItemForm.

ngOnInit() {
 this.uploader.onBuildItemForm = (fileItem: any, form: any) => {
  form.append('someField', this.someValue); //note comma separating key and value
  form.append('someField2', this.someValue2);
 };
}

The instance form is of type FormData. By looking at my HTTP post, I can see my form field values being sent to the server, and my server actually sees the values now.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Jane Wayne
  • 8,205
  • 17
  • 75
  • 120
  • When posting it this way, you are posting your 'someField' as multi-form-data so you won't be able to get it with req.body. You'll have to use another package like multer to get at the value and then it will attach 'someField' as req.body. – VtoCorleone Aug 09 '16 at 17:20
  • @JaneWayne do you know how this would work if I would want to uploade multiple files and attach different information to all of them? – Androidicus Nov 24 '16 at 17:10
  • 7
    Just adding a detail that might trip some people up: The form.append method is: `form.append('key',value);` *Note the comma separation between name & value, not colon. – jacobedawson Mar 11 '17 at 16:52
  • @Jane Wayne, How to access those passed additional value in server side? – Hitesh Jun 22 '17 at 09:47
  • I have just used this portion of the logic inside a separate function which will be called on click of the upload button. Then trigger the upload. Something like this.. 'code' uploadMe(item) { this.uploader.onBuildItemForm = (fileItem: any, form: any) => { form.append('empid', '12345'); }; item.upload(); } – Prem Ananth C Jul 01 '17 at 13:09
  • Thanks! You saved my day ! :) – dnx Dec 14 '17 at 14:34
8
this.uploader.onBeforeUploadItem = (item: FileItem) => {
  item.withCredentials = false;
  this.uploader.authToken = 'Bearer ' + this.boxTokenResponse.userToken;
  this.uploader.options.additionalParameter = {
    name: item.file.name,
    parent_id: this.parentFolderId
  };
};

This is how file-uploader.class.js pans the form data.

if (!this.options.disableMultipart) {
        sendable = new FormData();
        this._onBuildItemForm(item, sendable);
        sendable.append(item.alias, item._file, item.file.name);
        if (this.options.additionalParameter !== undefined) {
            Object.keys(this.options.additionalParameter).forEach(function (key) {
                sendable.append(key, _this.options.additionalParameter[key]);
            });
        }
    }
0

As for accessing the data in server, it can be done using Multer:

    const multer = require('multer');
    let DIR = './uploads/';

    let upload = multer({dest: DIR}).single('givenitemAlias');
        router.post('/upload', function (req, res, next) {
            console.log(req.body);//empty object
            upload(req, res, function (err) {
                if (err) {
                    // An error occurred when uploading
                    return res.status(422).send("an Error occured")
                }
                // No error occured.
                console.log(req.body);//modified req.body with out key value pairs
                console.log(req.file);//metadata of the file
                return res.send("Upload Completed for "+temppathOfUploadedFile);
            });            
        });
dasfdsa
  • 7,102
  • 8
  • 51
  • 93