I'm using restangular 1.51 with angular 1.6. My html looks like this
<input type="file" name="file" />
and the angular code (based on the discussion here):
let directive = {
..
link: (scope, element, attrs) => {
let inputElement = angular.element(element[0].querySelector('input'));
inputElement.bind('change', function () {
var formData = new FormData();
formData.append('file', inputElement[0].files[0]);
API.all('stores/csv').withHttpConfig({transformRequest: angular.identity}) .customPOST(formData,'' , undefined,
{ 'Content-Type': undefined }).then((response) => {console.log(response);
});
});
laravel code:
public function upload(Request $request)
{
$this->validate($request, [
'file' => 'required',
'type' => 'in:csv,xls,xlsx',
]);
$file = $request->file('file');
var_dump($file);
return response()->success(['file' => $file]);
}
thing is the $file here is appearing as an empty array in the laravel dump. The documentation is pretty bad on this. Ideas?
update
It works just fine using postman. this is the curl generated by postman:
postman curl:
curl -X POST \
http://127.0.0.1:8000/api/stores/csv \
-H 'Accept: application/x.toters.v1+json' \
-H 'Authorization: Bearer ***' \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Postman-Token: 4f9d2f3b-551b-aa47-4f65-98c7582f2919' \
-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
-F file=@/Users/Shared/Download/bac-383-store-update.csv
postman server logs
[2018-03-03 06:35:18] local.INFO: ----------------------------- [] []
[2018-03-03 06:35:18] local.INFO: POST api/stores/csv [] []
[2018-03-03 06:35:18] local.INFO: array ( 'file' => Illuminate\Http\UploadedFile::__set_state(array( 'test' => false, 'originalName' => 'bac-383-store-update.csv', 'mimeType' => 'text/csv', 'size' => 62, 'error' => 0, )), ) [] []
[2018-03-03 06:35:18] local.INFO: Status code: 200 [] []
[2018-03-03 06:35:18] local.INFO: User id: 104 [] []
this is the curl generated by restangular
restangular (two requests - using chrome) curl:
curl 'http://127.0.0.1:8000/api/stores/csv'
-X OPTIONS
-H 'Access-Control-Request-Method: POST'
-H 'Origin: http://localhost:3000'
-H 'Accept-Encoding: gzip, deflate, br'
-H 'Accept-Language: en-US,en;q=0.9'
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36'
-H 'Accept: */*'
-H 'Connection: keep-alive'
-H 'Access-Control-Request-Headers: authorization,content-type'
--compressed
curl 'http://127.0.0.1:8000/api/stores/csv'
-H 'Origin: http://localhost:3000'
-H 'Accept-Encoding: gzip, deflate, br'
-H 'Accept-Language: en-US,en;q=0.9'
-H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjEwNCwiaXNzIjoiaHR0cDpcL1wvMTkyLjE2OC4wLjIzMjo4MDAwXC9hcGlcL3VzZXJzXC9sb2dpbiIsImlhdCI6MTUxOTk2OTAzNiwiZXhwIjoxNjE0NTc3MDM2LCJuYmYiOjE1MTk5NjkwMzYsImp0aSI6IndHV0UzRjhYQ3hRdDBGOWMifQ.XqySEIprbxtAU-RfhOgtFkScN1nUuuXEwMxCltfjqu8'
-H 'Content-Type: application/json'
-H 'Accept: application/x.toters.v1+json'
-H 'Referer: http://localhost:3000/?local/'
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36'
-H 'Connection: keep-alive'
--data-binary $'------WebKitFormBoundary9ApCHw2ykmLYK2IY\r\nContent-Disposition: form-data; name="file"; filename="bac-383-store-update.csv"\r\nContent-Type: text/csv\r\n\r\n\r\n------WebKitFormBoundary9ApCHw2ykmLYK2IY--\r\n' --compressed
restangular/chrome server logs
[2018-03-03 06:34:52] local.INFO: ----------------------------- [] []
[2018-03-03 06:34:52] local.INFO: OPTIONS api/stores/csv [] []
[2018-03-03 06:34:52] local.INFO: array ( ) [] []
[2018-03-03 06:34:52] local.INFO: Status code: 200 [] []
[2018-03-03 06:34:52] local.INFO: ----------------------------- [] []
[2018-03-03 06:34:52] local.INFO: POST api/stores/csv [] []
[2018-03-03 06:34:52] local.INFO: array ( ) [] []
[2018-03-03 06:34:52] local.INFO: Status code: 200 [] []
[2018-03-03 06:34:52] local.INFO: User id: 104 [] []
update 2:
after comparing the headers between both curls, i noticed that the content type was different:
postman curl snippet
-H 'Content-Type: application/x-www-form-urlencoded' \
restangular curl snippet
-H 'Content-Type: application/json'
this was shocking, considering that the rectangular people PROMISED that by using the above syntax, the content type should be application/x-www-form-urlencoded
:
Restangular.all('users') .withHttpConfig({transformRequest: angular.identity}) .customPOST(formData, undefined, undefined, { 'Content-Type': undefined }); This basically tells the request to use the Content-Type: multipart/form-data as the header.
so I wrote this:
API.all('stores/csv').withHttpConfig({transformRequest: angular.identity})
.customPOST(formData, undefined, undefined,
{ 'Content-Type': 'application/x-www-form-urlencoded' }).then((response) => {console.log(response);
this improved things a bit.. compare the two curls now:
postman
curl -X POST \
http://127.0.0.1:8000/api/stores/csv \
-H 'Accept: application/x.toters.v1+json' \
-H 'Authorization: Bearer ***' \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Postman-Token: 4f9d2f3b-551b-aa47-4f65-98c7582f2919' \
-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
-F file=@/Users/Shared/Download/bac-383-store-update.csv
angular
curl 'http://127.0.0.1:8000/api/stores/csv'
-H 'Origin: http://localhost:3000'
-H 'Accept-Encoding: gzip, deflate, br'
-H 'Accept-Language: en-US,en;q=0.9'
-H 'Authorization: Bearer ***
-H 'Content-Type: application/x-www-form-urlencoded'
-H 'Accept: application/x.toters.v1+json'
-H 'Referer: http://localhost:3000/?local/'
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36'
-H 'Connection: keep-alive'
--data $'------WebKitFormBoundaryd405EnTxpFJv2GDN\r\nContent-Disposition: form-data; name="file"; filename="bac-383-store-update.csv"\r\nContent-Type: text/csv\r\n\r\n\r\n------WebKitFormBoundaryd405EnTxpFJv2GDN\r\nContent-Disposition: form-data; name="name"\r\n\r\nfile\r\n------WebKitFormBoundaryd405EnTxpFJv2GDN--\r\n'
--compressed
so i'm still not sending the -F
option