Search code examples
angularjslaravelng-file-upload

could not upload properly using ng-file-upload and laravel


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);
        }
    }
}

Solution

  • 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)
    });