12

I have

enter image description here

Browse files button

<input type="file" upload-files multiple />

Create Button

<button class="btn btn-link" ng-click="store()" >Create</button>

Directive

myApp.directive('uploadFiles', function () {
    return {
        scope: true,
        link: function (scope, element, attrs) {
            element.bind('change', function (event) {
                var files = event.target.files;
                for (var i = 0; i < files.length; i++) {
                    scope.$emit("seletedFile", { file: files[i] });
                }
            });
        }
    };
});

Listen for the file selected

$scope.files = [];
$scope.$on("seletedFile", function (event, args) {

    console.log("event is ", event);
    console.log("args is ", args);

    $scope.$apply(function () {
        $scope.files.push(args.file);
    });

});

Post data and selected files.

$scope.store = function() {

    $scope.model = {
      name: $scope.name,
      type: $scope.type
    };

    $http({
        method: 'POST',
        url: '/image/store',
        headers: { 'Content-Type': undefined },
        transformRequest: function (data) {
            console.log("data coming into the transform is ", data);
            var formData = new FormData();
            formData.append("model", angular.toJson(data.model));
            for (var i = 0; i < data.files; i++) {
                formData.append("file" + i, data.files[i]);
            }
            return formData;
        },

        data: { model: $scope.model, files: $scope.files }

    })


    .then(function successCallback(response) {
        console.log("%cSuccess!", "color: green;");
        console.log(response);
        $scope.refresh();
        $scope.showModal = false;
        }, function errorCallback(response) {
        console.log("%cError", "color: red;");
        console.log(response);
    });
};

Result

In my console, I don't see my files got pass on to my controller in the back-end.

array:1 [
  "model" => "{"type":"wedding"}"
]

Questions

What steps did I forget?

How would one go about and debug this further ?


1

5 Answers 5

2

I've done several angular 1 projects and also find it is not simple to upload files via $http api. Hope below code snippet which i used in my projects may help you.

$scope.store = function() {
  var formData = new FormData();

  // add normal properties, the name should be the same as
  // what you would use in a html form
  formData.append('model[name]', $scope.name);
  formData.append('model[type]', $scope.type);

  // add files to form data.
  for (var i = 0; i < $scope.files; i++) {
    formData.append('file' + i, $scope.files[i]);
  }

  // Don't forget the config object below
  $http.post('/image/store', formData, {
    transformRequest: angular.identity,
    headers: {'Content-Type': undefined}
  }).then(function() {
    // ...
  });
};
Sign up to request clarification or add additional context in comments.

Comments

1

Here some suggestions for you:

  1. Make the Content-type sets to multipart/form-data to set the content type to something like.... "it has some part in it, please make sure you get it properly" thing.
  2. Use Axios. Here's a working examples (if you didn't use Axios, this example are good too). Example to Axios on Uploading File.

2 Comments

I updated my headers: { 'Content-Type': undefined }, --> headers: { 'Content-Type': 'multipart/form-data' }, - still didn't work.
Can we see your PHP script too?
1

You can use FormData instead

var formData = new FormData();

  formData.append('model[var]', $scope.var);

  // For add to the FormData other file
  for (var i = 0; i < $scope.files; i++) {
    formData.append('file' + i, $scope.files[i]);
  }

 // POST REQUEST MUST BE:
  $http.post('url', formData, {
    transformRequest: angular.identity,  //It is for allowing files
    headers: {'Content-Type': undefined}
    }).then(function(response) 
  {
    // verify if response get 200
  });

Comments

1

I am not very experienced in Angular, so I'm assuming that your front-end works.

Debugging Tip Create a PHP file called...I dunno...file_dump.php. In that file, put this code:

<?php
    echo "<pre>"
    print_r($_REQUEST)
    echo "</pre>"
?>

and submit your form to that. That will show you all your request data. If you do not see your files in the output, it is a problem with your JavaScript. Since I am not that good at Angular, I'm going to point you to this link: link to multiple file upload tutorial using Angular. These guys seem to know what they're doing.

If you do see your files in the file_dump.php output, it's a problem with your backend - Laravel. This, I can help you with, but I need to see your scripts for me to be helpful in this aspect.

Please do post the results of file_dump.php.

Also, are you using the correct methods for fetching files? Link. If not, then we have found our culprit...

=D
Pranav

Comments

1

It is my directive:

app.directive('fileModel', ['$parse', 'message', function ($parse, message) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {

            var model = $parse(attrs.fileModel);
            var modelSetter = model.assign;

            //This part is for validate file type in current case must be image
            element.bind('change', function (e) {
                if (attrs.onlyImages == 'true') {
                    if (element[0].files[0].name.substring(element[0].files[0].name.lastIndexOf('.')) != '.jpg'
                        && element[0].files[0].name.substring(element[0].files[0].name.lastIndexOf('.')) != '.jpeg'
                        && element[0].files[0].name.substring(element[0].files[0].name.lastIndexOf('.')) != '.png'
                        && element[0].files[0].name.substring(element[0].files[0].name.lastIndexOf('.')) != '.gif'
                        && element[0].files[0].name.substring(element[0].files[0].name.lastIndexOf('.')) != '.bmp'
                    ) {
                        message.error("This field only accept files of type images(jpg,png)");
                        element.attr('is_valid', false);
                        return false;
                    } else {
                        element.attr('is_valid', true);
                    }
                }
                scope.$apply(function () {
                    modelSetter(scope, element[0].files[0]);
                });
            });
        }
    };
}]);

the html:

<input type="file" only-images="true" file-model="data.image" >

And Js Controller fragment:

 var fd = new FormData();
 fd.append('fileImage', data.image);

 $http.post('http://url.com', fd, {
                transformRequest: angular.identity,
                headers: {'Content-Type': undefined,}
            })

On laravel to get and copy image: is clear on the docs

https://laravel.com/docs/5.4/requests#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.