2

I am trying to implement a feature so that the user will be able to upload a profile photo for our company page. I am using ng-file-upload plugin in angular: https://github.com/danialfarid/ng-file-upload

I followed one example in the documentation for uploading a photo:

    function uploadPic ( file ) {
        file.upload = Upload.upload( {
            url: 'api/companyprofile/upload_logo',
            method: 'POST',
            sendFieldsAs: 'form',
            headers: {
                'my-header': 'my-header-value'
            },
            file: file,
            fileFormDataName: 'myLogo.png'
        } );

        file.upload.then( function ( response ) {
            $timeout( function () {
                file.result = response.data;
            } );
        }, function ( response ) {
            if ( response.status > 0 )
                logger.error( response )
        } );

        file.upload.progress( function ( evt ) {
            // Math.min is to fix IE which reports 200% sometimes
            file.progress = Math.min( 100, parseInt( 100.0 * evt.loaded / evt.total ) );
        } );
    }

and this is it's html

                            <form name="myForm" enctype="multipart/form-data">
                                <fieldset>
                                    <legend>Upload on form submit</legend>
                                    <br>Photo:
                                    <input type="file" ngf-select ng-model="picFile" name="cp_logo" accept="image/*" ngf-max-size="2MB" required>
                                    <i ng-show="myForm.file.$error.required">*required</i>
                                    <br>
                                    <i ng-show="myForm.file.$error.maxSize">File too large 
      {{picFile.size / 1000000|number:1}}MB: max {{picFile.$errorParam}}</i>
                                    <img ng-show="myForm.file.$valid" ngf-src="!picFile.$error && picFile" class="thumb">
                                    <br>
                                    <button ng-click="vm.uploadPic(picFile)">Submit</button>
                                    <span class="progress" ng-show="picFile.progress >= 0">
    <div style="width:{{picFile.progress}}%" 
        ng-bind="picFile.progress + '%'"></div>
  </span>
                                    <span ng-show="picFile.result">Upload Successful</span>
                                    <span class="err" ng-show="errorMsg">{{errorMsg}}</span>
                                </fieldset>
                                <br>
                            </form>

The problem is that I get a status code of 200 telling me that it had uploaded the photo successfully but in reality it did not. Giving me an empty response. What am I doing wrong?

Disclaimer: I don't know php but this is the backend code from our backend developer. This might help

/**
 * Upload a Company Logo (Synchronous).
 * @route GET - prefix/companyprofile/upload_logo
 *
 * @return json
 */
public function uploadLogo() 
{
    // get the company profile object
    $cProfile = CompanyProfile::first();
    // get all inputs from the form
    $input = Input::all();
    // needs validation
    $validator = Validator::make(Input::all(), ['cp_logo' => 'image|max:'.$this->max_filesize]);
    if ($validator->fails()) {
        return array('error' => $validator->messages());
    }
    // if there is a cp_logo store in $file variable
    if($file = array_get($input,'cp_logo')) {
        // delete old company logo
        $this->deleteOldCompanyLogo($cProfile);
        // concatenate the filename and extension
        $input['filename'] = $this->generateFileName($file);
        // save the company logo filename in the database
        $this->saveCompanyLogo($cProfile, $input['filename']);
        try {
            // upload the files to the file server
            Storage::disk(env('FILE_STORAGE'))->put($input['filename'],  File::get($file));
            return response()->json(['status' => 'Upload successful', 'filename' => $input['filename']]);
        } catch(\Exception $e) {
            return response()->json(['error' => $e->getMessage()], 400);
        }
    }
}
6
  • See if the file is actually being send in the network tab of the browser. If that's the case then it is a problem with php code not saving it properly. You can ask the backend dev to log if the file is actually being received. Commented Sep 3, 2015 at 4:47
  • I tried placing another parameter in the file.upload object @danial fields: {cp_logo: 'filename.png'}, and it now gives me a response of {"error":{"cp_logo":["The cp logo must be an image."]}} Commented Sep 3, 2015 at 5:01
  • 1
    my short answer: fileFormDataName: 'cp_logo' Commented Sep 3, 2015 at 5:22
  • 1
    It worked! Thank you so much! Can you explain to me the reason for this? @aifarfa Commented Sep 3, 2015 at 5:33
  • yeah, a simple html form uses <input name="..." as data-key but ng-file-upload override it with fileFormDataName field. :) Commented Sep 3, 2015 at 7:07

1 Answer 1

1

your backend expecting input named "cp_logo"

function uploadPic(file) {
    if (!file || file.$error) {
        logger.error(file);
        return;
    }
    file.upload = Upload.upload({
        url: 'api/companyprofile/upload_logo',
        method: 'POST',
        sendFieldsAs: 'form',
        headers: {
            'my-header': 'my-header-value'
        },
        file: file,
        fileFormDataName: 'cp_logo' //<-- here is your POST data key send to server
    });

and since in your html input named "cp_logo"

<input type="file" ngf-select ng-model="picFile" name="cp_logo" accept="image/*" ngf-max-size="2MB" required>

your validation expression should be.. myForm.cp_logo.$error or myForm.cp_logo.$valid

also double check upload input before send

HTML

<img ng-show="myForm.cp_logo.$valid" ngf-src="!picFile.$error && picFile" class="thumb">
<br>
<button ng-click="vm.uploadPic(picFile)" ng-disabled="!myForm.$valid" >Submit</button>

^ if this button is disabled obviously something wrong with inputs

BTW: the backend could return a status 200 (OK) when validation failed

you could check json response

file.upload.then(function(response) {
    $timeout(function() {
        logger.log(response.data); 
        if(response.data.error){
            //something went wrong?
        }
        file.result = response.data;
    });
}, function(response) {
    if (response.status > 0)
        logger.error(response)
});
Sign up to request clarification or add additional context in comments.

3 Comments

I checked the json response and it's very weird because it says status: 200 statusText: "OK"
I tried a simple html file for the upload without ng-file-upload or angular and it worked just fine <form action="upload_logo" method="post" enctype="multipart/form-data">
I was missing fileFormDataName: 'cp_logo'

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.