#laravel #vue.js #axios #crud
#laravel #vue.js #axios #crud
Вопрос:
я работаю над спа-центром laravel vuejs. Я пытаюсь обновить сообщение от администратора. Я отправляю данные формы при создании нового FromData, которые отправляются с запросом и axios.
Но контроллер отправляет мне сообщение об ошибке:
message: "The given data was invalid."
errors: {name: ["The name field is required."], description: ["The description field is required."]}
- Вот сообщение / edit.vue
<template>
<div class="post-edit">
<form id="form" @submit.prevent="createPost">
<!-- Title -->
<div class="form-group">
<label for="title" class="form-label">Title</label>
<input id="title" v-model="post.title" :title="post.title" type="text"
name="title" class="form-control"
>
</div>
<!-- Category -->
<div class="form-group">
<label for="category" class="form-label">Category</label>
<select id="category" v-model="post.category" :value="post.category" :category="post.category"
name="category" class="form-control"
>
<option disabled :value="post.category">
Choisir une catégorie
</option>
<option v-for="(category) in categories" :key="category.id" :value="post.category">
{{ category.name }}
</option>
</select>
</div>
<div class="post-edit-image">
<img :src="path post.image" alt="">
</div>
<!-- Image -->
<div class="form-group post-edit-select-image">
<label for="content" class="form-label">Image</label>
<input type="file" name="image" class="form-control" @change="selectedImage">
</div>
<!-- Content -->
<div class="form-group">
<label for="content" class="form-label">Content</label>
<editor
id="content"
v-model="post.content"
api-key="the-api-key"
:init="{
height: 500,
menubar: false,
plugins: [
'advlist autolink lists link image charmap print preview anchor',
'searchreplace visualblocks code fullscreen',
'insertdatetime media table paste code help wordcount'
],
toolbar:
'undo redo | formatselect | bold italic backcolor |
alignleft aligncenter alignright alignjustify |
bullist numlist outdent indent | removeformat | help'
}"
name="content"
:content="post.content"
/>
</div>
<!-- Submit Button -->
<button type="submit" class="btn btn-primary">
Sauvegarder
</button>
</form>
</div>
</template>
<script>
import axios from 'axios'
import { mapGetters } from 'vuex'
import Editor from '@tinymce/tinymce-vue'
export default {
middleware: 'auth',
components: {
'editor': Editor
},
props: ['id'],
data () {
return {
post: {
id: '',
user_id: '',
title: '',
category: '',
image: null,
content: ''
},
path: '/images/post/thumbnail/'
}
},
computed: {
...mapGetters({
user: 'auth/user',
categories: 'categories/categories'
})
},
beforeCreate () {
this.$store.dispatch('categories/fetchCategories')
},
created () {
this.getPostById(this.$route.params.id)
},
methods: {
selectedImage (event) {
this.post.image = event.target.files[0]
},
getPostById (id) {
axios.get('/api/posts/edit/' id)
.then((response) => {
this.post.id = response.data.id
this.post.user_id = response.data.user_id
this.post.title = response.data.title
this.post.category = response.data.category
this.post.image = response.data.image
this.post.content = response.data.content
})
.catch((error) => {
console.log(error)
})
},
createPost (e) {
this.post.userId = this.user.id
let formData = new FormData(e.target)
let id = this.post.id
formData.append('title', this.post.title)
formData.append('category', this.post.category)
formData.append('image', this.post.image)
formData.append('content', this.post.content)
axios.patch('/api/posts/update/' id, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then((response) => {
console.log(response)
this.$store.dispatch('posts/fetchPosts')
})
.catch((error) => {
console.log(error)
})
this.$router.push({ name: 'admin' })
}
}
}
</script>
- И здесь контроллер laravel PostController@update метод
/**
* Update the specified resource in storage.
*
* @param IlluminateHttpRequest $request
* @param int $id
* @return IlluminateHttpResponse
*/
public function update(PostUpdateRequest $request, $id)
{
$post = Post::findOrFail($id);
$post->update($request->getValidRequest());
return response()->json($request, 200);
}
- И пользовательский валидатор PostUpdateRequest.php
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required|max:250|unique:posts,title',
'category' => 'required',
'image' => 'mimes:jpg,jpeg,png,bmp',
'content' => 'required'
];
}
public function getValidRequest()
{
$image = $this->file('image');
$slug = Str::slug($this->input('title'));
if (isset($image)) {
$imageExt = $image->getClientOriginalExtension();
$currentDate = Carbon::now()->toDateString();
$imageName = $slug . '-' . $currentDate . '-' . uniqid() . '.' . $imageExt;
if (!Storage::disk('public')->exists('post')) {
Storage::disk('public')->makeDirectory('post');
}
if (!Storage::disk('public')->exists('post/thumbnail')) {
Storage::disk('public')->makeDirectory('post/thumbnail');
}
$path = "images/";
$postImage = Image::make($image)->resize(null, 1060, function ($constraint){
$constraint->aspectRatio();
})->save(public_path($path).'post/'.$imageName);
$thumbnail = Image::make($image)->fit(550, 550)
->save(public_path($path).'post/thumbnail/'.$imageName);
}
return [
'user_id' => Auth::user()->getAuthIdentifier(),
'category_id' => $this->input('category'),
'title' => $this->input('title'),
'slug' => $slug,
'content' => $this->input('content'),
'image' => $imageName,
'is_published' => $this->input('is_published') ?? false,
];
}
- Маршрут api в laravel
Route::patch('/update/{id}', 'BackendPostController@update');
Я использую практически те же вещи для хранения post, и все работает нормально, единственное отличие в том, что здесь я передаю идентификатор для обновления post, и я использую не метод post, а patch для axios и маршрута (и я пытаюсь с помощью put, это та же ошибка).
спасибо за ваше время!
Ответ №1:
добавьте поле ‘_method’ со значением ‘PATCH’ в FormData
formData.append('_method', 'PATCH')
и отправьте запрос axios post для обновления данных
axios.post('/api/posts/update/' id, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})