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
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);
},
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.
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 ?
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));
}
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