empty file when upload a mediaObject - php

When I try to upload a file on my Symfony API, I have an error from MediaObjectAction.php which is a controller.
This file looks like this :
final class CreateMediaObjectAction extends AbstractController
{
public function __invoke(Request $request): MediaObject
{
$uploadedFile = $request->files->get('file');
if (!$uploadedFile) {
throw new BadRequestHttpException('"file" is required');
}
$mediaObject = new MediaObject();
$mediaObject->file = $uploadedFile;
return $mediaObject;
}
}
and it throws me the error : "file" is required
In the front-end, I use ReactJS and I do a simple file upload with these functions :
const handleFileChange = (event) => {
console.log(event.target.files[0])
setFile({ selectedFile: event.target.files[0], loaded: 0 })
}
const uploadFile = () => {
FileUtils.uploadFile(MEDIA_OBJECT_ENDPOINT, file.selectedFile)
.then((response) => {
console.log(response)
})
const FileUtils = {
uploadFile: async (url, file) => {
const data = new FormData()
data.append('name', 'file')
data.append('file', file)
const response = await api.post(url, data)
return response
},
}
And in html, the file input looks like this :
<input
type="file"
id="file"
name="file"
onChange={handleFileChange}
></input>
As you can see, it is very basic, but it does not work and I cannot figure out why. Do you have an idea of what I miss ?
PS : The function api.post() works very well, the problem does not come from it.

Related

FilePond send a blank request to server

i use Laravel-filepond and Vue FilePond.
but FilePond send a blank request to server.
this is my codes:
*UserComponent.vue
<template>
<div class="container">
<file-pond
name="Profile"
ref="pond"
label-idle="drag & drop"
v-bind:allow-multiple="false"
accepted-file-types="image/jpeg, image/png"
v-bind:files="userFile"
v-bind:server="{
url: '/panel/filepond',
timeout: 7000,
process: {
url: '/process',
method: 'POST',
headers: {
'X-CSRF-TOKEN': this.get_meta('csrf-token'),
},
}
}"
v-on:init="handleFilePondInit"/>
</div>
</template>
<script>
import vueFilePond, {setOptions} from 'vue-filepond';
import 'filepond/dist/filepond.min.css';
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css';
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
import FilePondPluginImageEdit from 'filepond-plugin-image-edit';
const FilePond = vueFilePond(FilePondPluginFileValidateType, FilePondPluginImagePreview);
export default {
data() {
return {
userFile: [],
}
},
methods: {
handleFilePondInit: function () {
console.log('FilePond has initialized');
}
},
components: {
FilePond
},
}
</script>
FilePondController.php Original file
<?php
namespace Sopamo\LaravelFilepond\Http\Controllers;
use function dd;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;
use Sopamo\LaravelFilepond\Filepond;
class FilepondController extends BaseController
{
private $filepond;
public function __construct(Filepond $filepond)
{
$this->filepond = $filepond;
}
public function upload(Request $request)
{
dd($request->all());
}
}
when I upload a file on client side (in default response with 422), I can not find it on my server.
FrameWorks & Repository is on last version.
Response
[]
According to the author, you are sending the metadata instead of the file itself. I solved this using the advanced custom process function that you can found in documentation. There you can find the comments about what almost every part of the code does.
data() {
return {
server: {
url: 'http://base-url.test',
process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
const formData = new FormData();
formData.append(fieldName, file, file.name);
const request = new XMLHttpRequest();
request.open('POST', 'url-to-post-to');
request.setRequestHeader('X-CSRF-TOKEN', 'your-csrf-token');
request.upload.onprogress = (e) => {
progress(e.lengthComputable, e.loaded, e.total);
};
request.onload = function () {
if (request.status >= 200 && request.status < 300) {
load(request.responseText);
} else {
error('Error');
}
};
request.send(formData);
return {
abort: () => {
request.abort();
abort();
},
};
},
},
}
},
Then you only need to bind it:
<template>
<div class="container">
<file-pond
name="Profile"
ref="pond"
label-idle="drag & drop"
v-bind:allow-multiple="false"
accepted-file-types="image/jpeg, image/png"
v-bind:files="userFile"
v-bind:server="server"
v-on:init="handleFilePondInit" />
</div>
</template>
responseText is the unique Id from the server. Maybe you want to emit it to parent component:
data() {
return {
server: {
url: 'http://base-url.test',
process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
const thisReference = this;
// Other code
request.onload = function () {
if (request.status >= 200 && request.status < 300) {
thisReference.
thisReference.$emit('my-event', request.responseText);
load(request.responseText);
} else {
error('Error');
}
};
// Other code
},
},
}
},
Pretty similar if you want to know what file has been reverted (in this case, you need to response from server with the same id you sent):
data() {
return {
server: {
// Process, url, etc.
revert: {
url: '/url-to-delete',
method: 'DELETE',
headers: {
'X-CSRF-TOKEN': 'your-csrf-token'
},
onload: (idDeleted) => this.$emit('my-event', idDeleted)
},
},
}
},

Problems with uploading file using Vue.js and Laravel

Vue template (File upload): This input field is generated from another module, Where the from generated by drag and drop input field.
<input type="file" #change="uploadFile(data,$event)" class="custom-file-input" id="validatedCustomFile">
Script Vuejs:
data () {
return {
//baseform
baseForm: new Form({
form:this.data ? JSON.parse(this.data.dataForm) : '',
}),
}
},
methods: {
uploadFile(data,e){
let file = e.target.files[0];
data.value = file;
},
// form data submit
formSubmit() {
const config = {
headers: {'Content-Type': 'multipart/form-data'}
}
let formData = new FormData();
formData.append('form',JSON.stringify(this.baseForm.form));
axios.post('/api/order-data',formData, config)
.then((order)=>{
//
}).catch(()=>{
//
})
}
}
Controller: Here is the controller code
$formData = json_decode($request->form, true);
foreach ($formData as $key) {
if($key['field'] == 'fileUpload') {
dd($key['value']);
}
}
I am getting empty value after die dump $key['value']

How to fix error when trying to upload file to backend?

I'am trying to upload a file to the server by using a service which passes the file to the php backend.
It works, but only once. If I try to repeat uploading another file (without reloading the page) it does not get send and this error occurs:
ERROR TypeError: "this.fileManagerService.uploadFile is not a function"
playground.component.html
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<input type="file" name="avatar" (change)="onFileSelect($event)" />
<button type="submit">Upload</button>
</form>
playground.component.ts
export class PlaygroundComponent implements OnInit {
form: FormGroup;
fileManagerResponse;
constructor(private formBuilder: FormBuilder, private fileManagerService: FileManagerService) { }
ngOnInit() {
this.form = this.formBuilder.group({
avatar: ['']
});
}
onFileSelect(event) {
if (event.target.files.length > 0) {
const file = event.target.files[0];
this.form.get('avatar').setValue(file);
}
}
onSubmit() {
const formData = new FormData();
formData.append('avatar', this.form.get('avatar').value);
this.fileManagerService.uploadFile(formData).subscribe(
(res) => {
this.fileManagerService = res;
console.log(res);
},
(err) => {
console.log(err);
}
);
}
}
FileManagerService.ts
export class FileManagerService {
SERVER_URL: string = "http://127.0.0.1/backend/api/";
constructor(private httpClient: HttpClient) { }
public uploadFile(data) {
let uploadURL = `${this.SERVER_URL}/filemanager/upload.php`;
return this.httpClient.post<any>(uploadURL, data);
}
}
The error occurred in below line.
this.fileManagerService = res;
You cannot assign res to the instance of the FileManagerService.
Remove it. Everything will be fine.

How to send a file via Axios to Laravel

I need to post a File from client to server via Axios.
Here is my Vuejs code :
methods: {
'successUpload': function (file) {
const config = { headers: { 'Content-Type': 'multipart/form-data' } };
axios.post('/Upload/File',file, config).then(function (response) {
console.log(response.data);
});
}
}
And here is my Laravel code for handling sent file :
public function uploadFile(Request $request)
{
if($request->hasFile('file'))
return "It's a File";
return "No! It's not a File";
}
But it always returns No It's not a File.
Any helps would be great appreciated.
You have to create a FormData object and append the image file.
methods: {
'successUpload': function (file) {
let data = new FormData();
data.append('file', document.getElementById('file').files[0]);
axios.post('/Upload/File',data).then(function (response) {
console.log(response.data);
});
}
}
An example is here.
Let me know if that works.

Get File Input Value in Laravel Via AngularJS form

I want to get value from file input from angularjs form in laravel, but i can't get the value.
why?
angularjs:
<div ng-controller="UploadImgController" >
<div ng-repeat="image in images">
<img ng-src="{{image.image}}" />
</div>
<form ng-submit="uploadImg()" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="path" id="path" ng-model="addimages.path" accept="image/*" app-filereader>
<input type="text" name="propertyid" ng-model="addimages.propertyid">
<input type="submit" value="Upload Image" name="submit" class="btn btn-primary" >
</form>
</div>
laravel (UploadImgController.php):
public function store()
{
$file = Input::file('path');
echo "file: ".$file;
}
(routes.php):
Route::resource('img','UploadImgController');
I got no value. What should I do? Thank you. :)
I recommend using ng-file-upload.
View
<button ng-file-select ng-model="myFiles" ng-file-change="upload($files)">Upload</button>
Angular JS
var app = angular.module('fileUpload', ['angularFileUpload']);
app.controller('MyCtrl', ['$scope', '$upload', function ($scope, $upload) {
$scope.upload = function (files) {
if (files && files.length){
for (var i = files.length - 1; i >= 0; i--) {
var file = files[i];
$upload.upload({
url: '/upload',
fields: {key: 'value'},
file: file
})
.progress(function (evt) {
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
console.log('File upload ' + progressPercentage + "% complete.");
})
.success(function (data, status, headers, config) {
console.log(data);
})
.error(function(data, status, headers, config) {
console.log(data);
});
}
}
};
}
]);
Laravel Route
Route::post('upload', [
'uses' => 'FileUploadController#upload'
]);
Laravel Controller
public function upload() {
$file = \Input::file('file');
return $file;
}
You can pull that off without a plugin actually. I did face a similar problem once and this is how I went about it.
View
<input type="file" name="file" onchange="angular.element(this).scope().uploadImage(this.files)"/>
Angularjs Controller
$scope.uploadavtar = function (files) {
var fd = new FormData();
//Take the first selected file
fd.append("file", files[0]);
$http.post("/upload-url" + $scope.school.profile.id, fd, {
withCredentials: true,
headers: {'Content-Type': undefined},
transformRequest: angular.identity
}).then(function successCallback(response) {
$scope.result = response;
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
console.log(response);
// called asynchronously if an error occurs
// or server returns response with an error status.
});
}
Routes.php
Route::post('/upload-url', 'UsersController#uploadFile');
Laravel Controller
// Upload files
public function uploadFile(Requests\UpdateuploadfileRequest $request, $id)
{
$extension = Input::file('file')->getClientOriginalExtension();
$fileName = time().'.'.$extension; // renameing image
$destination = 'uploads/img'. $fileName;
move_uploaded_file($_FILES['file']['tmp_name'], $destination);
}
}
Request validation file (UpdateuploadfileRequest.php)
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
$rules = [
];
return $rules;
}

Categories