Vue / Laravel - Formdata.append displaying null value on edit - laravel

I have a working post method for storing a photo + the first name of the user.
// front-end
let formData = new FormData();
formData.append('photo', this.tableItem.photo);
formData.append('first_name', this.tableItem.first_name);
await axios.post('/api/employees', formData, { headers: { 'Content-Type': 'multipart/form-data' }})
// back-end
$employee = Employee::create([
'first_name' => $request->first_name,
]);
Now if I edit the first_name, the put method is a success but the value is displayed as blank
Object.assign(this.tableData[this.editedIndex], this.tableItem)
let formData = new FormData();
formData.append('photo', this.tableItem.photo);
formData.append('first_name', this.tableItem.first_name);
await axios.put('/api/employees/' + this.tableItem.id, formData, { headers: { 'Content-Type': 'multipart/form-data' }})
$employee->update([
'first_name' => $request->first_name,
]);
If I removed the formData and replaced it with this.tableItem everything is working as intended. Even if a I put an await for Object.assign, the new value input is still not captured.

It is a known bug on PHP, Symfony and Laravel as well, a workaround is to append _method param with PATCH or PUT value to your formdata and use axios.post instead:
formData.append('_method', 'PUT');
await axios.post(
'/api/employees/' + this.tableItem.id,
formData,
//{...
Check this issue on Laravel repo for more info: https://github.com/laravel/framework/issues/13457#issuecomment-340156084

Related

Multipart/form-data not working on axios put request

I am now trying to make a crud functionality with file upload on my project. I have done the creation part and it's all working fine since I implemented that with new FormData() by appending the file value and sending post request from axios with headers 'Content-Type': 'multipart/form-data'.
However, axios sends an empty body if I pass 'Content-Type': 'multipart/form-data' in the headers. If I remove it, it sends the actual object but without the uploaded file. I am implementing this on NextJs with Laravel backend.
Here's the code
const formData = new FormData();
formData.append('first_name', values.first_name);
formData.append('last_name', values.last_name);
formData.append('phone_no', values.phone_no);
formData.append('profile_picture', values.profile_picture, 'bermuda.png');
formData.append('password', values.password);
await axios
.put(`/api/v1/users/${user.member_no}`, formData,
{
headers: {'Content-Type': 'multipart/form-data'}
})
.then((res) => {
console.log(res.data);
if (res.status === 201) {
toast.success('Member updated successfully.');
refreshUser(); // mutating the swr request
}
})
.catch((err) => {
toast.error(err.response.data.message);
});
setLoading(false);
},
console.log(res.data); from axios returns [] if I pass multipart/form-data or it returns the whole value object if i remove it but wihout the uploaded file.```
This seems to be a common re-occurring problem within Laravel projects. Not sure if it's caused by Axios or Laravel itself, but for the meantime, the following workaround works:
Instead of sending an actual HTTP PUT request, send an HTTP POST request with a parameter in your formData named _method with its value set to put. This is a feature in Laravel known as method spoofing.
Adding that field to your formData, your code would look like this:
const formData = new FormData();
formData.append('_method', 'put');
formData.append('first_name', values.first_name);
formData.append('last_name', values.last_name);
formData.append('phone_no', values.phone_no);
formData.append('profile_picture', values.profile_picture, 'bermuda.png');
formData.append('password', values.password);
await axios
.post(`/api/v1/users/${user.member_no}`, formData,
{
headers: {'Content-Type': 'multipart/form-data'}
})
.then((res) => {
console.log(res.data);
if (res.status === 201) {
toast.success('Member updated successfully.');
refreshUser(); // mutating the swr request
}
})
.catch((err) => {
toast.error(err.response.data.message);
});
setLoading(false);
},

How do I pass a file uploaded from vue front end to laravel controller?

I have a file upload form in vue and want to pass the file data to a laravel controller. The data is passed from page to store fine in vue, but I can't access it in my controller:
vue page:
update() {
this.$store.dispatch('uploadDocument', {
file: this.form.file,
})
},
store:
axios.post('/users/newDocument', {
file: data.file,
})
If I console.log data.file, I can see the file is passed to post method:
'File {name: 'test2.txt', lastModified: 1633600501434, lastModifiedDate:......'
Route:
Route::post('/users/newDocument', [UserController::class, 'store']);
controller:
public function store(Request $request)
{
return $request;
}
but nothing is returned, even if I do $request->file, or $request->hasFile('file'):
'{data: {…}, status: 200, statusText: 'OK', headers: {…}, config: {…}, …}'
Any ideas what I'm missing? Do I need to first build the form data? (new FormData()). I've tried adding _method: 'PATCH' to the form and adding the header: 'Content-Type': 'multipart/form-data', but still nothing.
FIX:
in vue, pass the form data:
const formData = new FormData();
formData.append('name', this.form.file.name);
formData.append('document_type', this.form.document_type);
in vue store:
axios.post('/users/newDocument', formData, {'content-type': 'multipart/form-data'})
laravel controller:
$request->get('name')
You need to build the FormData first and send it though axios Wwthout forgetting to modify the header as you started to do it.

What is the reason for the appearance - object url is not defined?

I create the WordPress registration form by processing data through AJAX.But faced with the problem:
By clicking on the authorization button an error occurs in the console: object url is not defined
Here is my code in function.php
$translation_array = array( 'url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('ajax-nonce') );
wp_localize_script('ajax_event', 'object_url', $translation_array);
And here is my js code:
jQuery('#login-form button').on('click',function(e){
var username = jQuery('#login-form').find('input[name=email]').val();
var password = jQuery('#login-form').find('input[name=password]').val();
data = {
'action': 'ginmagtheme_login',
'user_login': username,
'user_password': password,
}
jQuery.ajax({
type:'post',
url: object_url.url,
data: data,
cache: false,
success: function(data) {
window.location.href = "/profile/";
}
});
e.preventDefault();
});
Maybe I'm missing something, but I don't see any errors here. Please help me figure it out.
Has say in the documentation :
Works only if the script has already been added.
Did you have a wp_enqueue_script('ajax_event', ..., ...); before the wp_localize_script ?

Laravel & Vue.js API file uploading doesn't work

I have a problem with file uploading on my Laravel&Vue.js website using API
I get - 500 Server Error "SyntaxError: Unexpected token < in JSON at position 0"
I'm trying to create new value in my database, for this I use pop up form with image uploading and other fields like username, email, phone etc.
I've tested my API via Postman - it works fine, but when I try to create this directly on my website - it desn't work
you can check a function which must create new value(startup) in DB:
createStartup() {
fetch('/api/startup', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body: JSON.stringify(this.new_startup),
})
.then(res => res.json())
.then(res => {
$('#createStartUp').modal('hide');
alert('New Startup Created!');
// this.fetchStartups();
})
.catch(err => console.log(err));
}
I think the issue in Headers (I didn't use any Headers in Postman), when I tried to not use any Headers - it didn't wok too, also O tried to use Content-Type with bypass and unfortunately it didn't work
Also I think it must be helpful - how I get image in vue.js:
HTML:
<input id="upload_create" class="file-upload_input" type="file" #change="onFileSelected" >
JS (Vue.js):
onFileSelected(event) {
this.new_startup.startup_logo = event.target.files[0];
}
Thanks a lot guys for any ideas and helps!
You need to pass your data as form-data. Here is how I managed to send a file upload via Vue.js:
createStartup() {
let formData = new FormData();
formData.append('file', this.new_startup.startup_logo);
formData.append('anythingElse', JSON.stringify(this.someVariable);
// ... etc
fetch('/api/startup', {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data'
},
body: formData,
})
.then(res => res.json())
.then(res => {
$('#createStartUp').modal('hide');
alert('New Startup Created!');
// this.fetchStartups();
})
.catch(err => console.log(err));
}

How can I using put method to update data on the vue component?

My ajax axios like this :
let formData = new FormData()
formData.append('file', user.avatar)
formData.append('selected_data', JSON.stringify(user))
axios.post('/member/profile/update',
formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}
)
.then(response => cb(response))
.catch(error => ecb(error))
My routes like this :
Route::post('update', 'member\UserController#update')->name('member.profile.update');
If the script executed, it works. I success get the data sended
But here, I want to change post method to put method. Because this used to update profile
I change like this :
axios.put(...
And the routes :
Route::put('update', ...
I don't success get the data sended. The data sended is empty
How can I solve this problem?
Update :
If I console.log(user), the result like this :
Laravel uses method spoofing for PUT, use axios.post and add the following to your requests data:
data: {
...
_method: 'PUT',
...
}
You can do:
formData.append('_method', 'PUT')
Complete example using axios:
axios.post('/user', { _method: 'PUT', foo: 'bar' })
.then(function (response) { console.log(response); })
.catch(function (error) { console.log(error); });
Form method spoofing

Resources