0



I am trying to bind form-data along with image(s) from HTML page to Angular Controller, then append form-data with image data, and finally POST data to an API.

So I searched, and got to know that, sadly AngularJs doesn't have any directive for image files.
So the ultimate solution I got is to create a custom directive, append form-data with image(s), and then POST that data to server.

What I tried:

HTML

<form role="form" enctype="multipart/form-data" name="myForm">
<input type="text"  ng-model="UserName" required="required">
<input type="text"  ng-model="FirstName" required="required">
<input type="file"  ng-model="Image" required="required">
<button type="submit" ng-click="product()">save</button>
</form>


Custom Directive :

myApp.directive('fileModel', ['$parse', function ($parse) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var model = $parse(attrs.fileModel);
            var modelSetter = model.assign;

            element.bind('change', function(){
                scope.$apply(function(){
                    modelSetter(scope, element[0].files[0]);
                });
            });
        }
    };
}]);


POST Method :

scope.product = function() {
     var pro = $scope.pro;
     console.log('Form Data : ' + pro);
    var fd = new FormData();
    angular.forEach($scope.Image, function(file) {
        fd.append('file', file);
    });
    fd.append('pro', JSON.stringify($scope.product));
    $http.post('/products/createProduct', fd, {
            transformRequest: angular.identity,
            headers: {
                'Content-type': undefined
            }
        })
        .then(function(data) {
            $scope.ListProducts = data;
            console.log($scope.ListProducts );
        });

}


But the problem is, nothing is binding to the controller, and every-time my object is empty.
I even tried logging data to console, but got nothing inside data.
I don't know what I am doing wrong.
Please help..


Update

I am able to bind data, but while posting image-path along with other form-data I am getting all null.

angular.js:14642 Possibly unhandled rejection: {"data":null,"status":-1,"config":{"method":"POST","transfor‌​mRequest":[null],"tr‌​ansformResponse":[nu‌​ll],"jsonpCallbackPa‌​ram":"callback","url‌​":"/products/createP‌​roduct","data":{"pro‌​ductStock":[{"price"‌​:"","color":""}],"pr‌​oductThumbnail":{"0"‌​:{}}},"headers":{"Ac‌​cept":"application/j‌​son, text/plain, /","Content-Type":"application/json;charset=utf-8"}},"status‌​Text":""} error

4

2 Answers 2

0

I made improve to your code. Basically you was using ng-model, instead of file-model like your directive says, also fd.append File no need iteraction if only have one file. Check the code and the plnkr.

CONTROLLER

$scope.product = function() {
     var pro = $scope.pro;
     var fd = new FormData();

    fd.append('file', $scope.form.Image);
    fd.append('pro', JSON.stringify($scope.form));
    $http.post('/products/createProduct', fd, {
            transformRequest: angular.identity,
            headers: {
                'Content-type': undefined
            }
        })
        .then(function(data) {
            $scope.ListProducts = data;
            console.log($scope.ListProducts );
        });
  };

HTML

<form role="form" enctype="multipart/form-data" name="myForm">
    <input type="text"  ng-model="form.UserName" required="required">
    <input type="text"  ng-model="form.FirstName" required="required">
    <input type="file" file-model="form.Image" required="required">
    <button type="submit" ng-click="product()">save</button>
</form>

{{form.Image.name}}

PLNKR EXAMPLE

**UPDATE **

in the network could see this. when sending data. enter image description here

Sign up to request clarification or add additional context in comments.

19 Comments

Thanks for the answer.I am able to bind data, but while posting image-path along with other form-data I am getting all null.
in network tab on developers console in browser you can check if data is sending to the api, and how is the data names.
the formdata sendint has to parts one name file an other pro
if api is PHP $_FILE('file');
Just now I checked in network-tab , i am getting null.
|
0

The <input type=file> element does not by default work with the ng-model directive. It needs a custom directive:

Working Demo of "files-input" Directive that Works with ng-model

angular.module("app",[]);

angular.module("app").directive("filesInput", function() {
  return {
    require: "ngModel",
    link: function postLink(scope,elem,attrs,ngModel) {
      elem.on("change", function(e) {
        var files = elem[0].files;
        ngModel.$setViewValue(files);
      })
    }
  }
});
<script src="//unpkg.com/angular/angular.js"></script>
  <body ng-app="app">
    <h1>AngularJS Input `type=file` Demo</h1>
    
    <input type="file" files-input ng-model="fileArray" multiple>
    
    <h2>Files</h2>
    <div ng-repeat="file in fileArray">
      {{file.name}}
    </div>
  </body>


Thanks for the answer. I tried your code, and getting:

angular.js:14642 Possibly unhandled rejection: {"data":null,"status":-1,"config":{"method":"POST","transfor‌​mRequest":[null],"tr‌​ansformResponse":[nu‌​ll],"jsonpCallbackPa‌​ram":"callback","url‌​":"/products/createP‌​roduct","data":{"pro‌​ductStock":[{"price"‌​:"","color":""}],"pr‌​oductThumbnail":{"0"‌​:{}}},"headers":{"Ac‌​cept":"application/j‌​son, text/plain, /","Content-Type":"application/json;charset=utf-8"}},"status‌​Text":""} error

In my experience, the most common cause of status of a -1, is that the browser blocked the response because of a violation of Same Origin Policy.

For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and Fetch follow the same-origin policy. So, a web application using XMLHttpRequest or Fetch could only make HTTP requests to its own domain. To improve web applications, developers asked browser vendors to allow cross-domain requests.

The Cross-Origin Resource Sharing (CORS) mechanism gives web servers cross-domain access controls, which enable secure cross-domain data transfers. Modern browsers use CORS in an API container - such as XMLHttpRequest or Fetch - to mitigate risks of cross-origin HTTP requests.

See Use CORS to allow cross-origin access.

3 Comments

Thanks for the answer.I tried your code, and getting angular.js:14642 Possibly unhandled rejection: {"data":null,"status":-1,"config":{"method":"POST","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"/products/createProduct","data":{"productStock":[{"price":"","color":""}],"productThumbnail":{"0":{}}},"headers":{"Accept":"application/json, text/plain, /","Content-Type":"application/json;charset=utf-8"}},"statusText":""} error
Oh okay.If I am using <input type="file" files-input ng-model="product.productThumbnail" multiple> then only I am getting above error.But if I am using <input type="file" files-input ng-model="fileArray" multiple>, then there is no error,but that image name is not getting stored in database.
I am getting this value in network-tab:productThumbnail: {name: {0: {}},as you can see there is no image name.

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.