Tuesday, March 14, 2017

$http.post() multipart/form-data and JSON using AngularJS 1.5 and Laravel 5.4

I'm using Laravel 5.4 with AngularJS, I have two Models Product & Tag with a ManyToMany relationship.

I'm using a Resource Controller, and I need to add a Product with an image upload as JSON, this is the Form :

<form class="form" action="/products" method="POST" enctype="multipart/form-data">
    
    <input type="text"id="name" name="name" ng-model="newProduct.name" />
    <input type="text" id="price" name="price" ng-model="newProduct.price"/>
    <select id="tags" name="tags[]"  ng-model="newProduct.tags" multiple>
        <!-- The values here are the ids of the Types in the DB, I hardcoded them here for now-->
        <option value="1">TYPE 1</option>
        <option value="2">TYPE 2</option>
        <option value="3">TYPE 3</option>
    </select>
    <input type="file" name="file" id="file" file-input="files"/>
    <button type="button" ng-click="submit()">Upload</button>
</form>

This is the ProductController

public function store(Request $request) 
{
        $this->validate($request, [
            'name' => 'required',
            'price' => 'required',
            'file' => 'required|mimes:xls|max:2048'
        ]);

        $product = new Product();
        $product->name = $request->name;
        $product->price = $request->price;
        //The property "url" will be the full name of the product file.
        $product->url = $request->file->getClientOriginalName();
        $tags =  $request->tags;

        $file = $request->file;

        //Move Uploaded File
        $destinationPath = 'productsFiles';
        $file->move($destinationPath, $file->getClientOriginalName());

        $product->save();
        $product->tags()->attach($tags);
}

In my JS file I have

var app = angular.module('myApp', ['ngRoute', 'ui.bootstrap']);

//...

app.directive('fileInput', ['$parse', function ($parse) {
    return {
        restrict: 'A',
        link: function (scope, element, attributes) {
            element.bind('change', function () {
                $parse(attributes.fileInput)
                    .assign(scope,element[0].files);
                console.log(element[0].files[0]);
                scope.$apply()
            });
        }
    };
}]);

app.controller('MainController', ['$scope', '$http', function($scope, $http) {

$scope.newProduct = {};
$scope.addProduct = function() {
$http.post("/products", $scope.newProduct )
    .then(function(response){
        console.log(response.status);
    }, function(err){
        console.log(err);
    });
};
$scope.submit = function() {
    $scope.addProduct();
};

}]);

I need to modify the $http.post() method so I can use my current Form to submit it as multipart with JSON, so I can access the $request properties as I did in my ProductController. I know I need to use JS formData object, but I have no idea how to use it.

Thank you very much in advance.



via dwix

Advertisement