I have a view where I'm displaying a form for data submissions (textarea and submit button) and a list of the user's latest posts (limited to 5) underneath it.
Each post has a button to save/favorite it to user's account.
The problem is that I am unable to pass the post ID on the post request.
I tried to pass the value of a hidden field that is populated by the post id, but it didn't work.
App\Models\User::favorite(): Argument #1 ($object) must be of type Illuminate\Database\Eloquent\Model, null given, called in C:\wamp64\www\write\app\Http\Controllers\PostController.php on line 70
All I need to do is pass post.id inside the vue loop to the save() method in PostController.php
Controller
public function index()
{
$posts = Post::where('user_id', '=', Auth::id())
->limit(5)
->orderBy('created_at','desc')
->get();
return Inertia::render('Post', [
'posts' => $posts
]);
}
public function save(Request $request) {
$user = User::find(Auth::id());
$post = $request->input('postId');
$user->favorite($post);
if($user) {
return redirect()->back()->with('message', 'Post Saved!');
} else {
return 'something went wrong';
}
}
HTML
<form @submit.prevent="" class="d-flex justify-content-between gap-3">
<div class="row w-100">
<!-- <input type="text" class="form-control" name="inputText" id="inputText"
v-model="form.inputText"> -->
<div class="col-12">
<textarea class="form-control" name="inputText" id="inputText"
placeholder="start writing..." rows="3" v-model="form.inputText"></textarea>
</div>
<div class="col-12 mt-2">
<button type="submit" class="btn btn-primary"
@click.prevent="post(form)">Post</button>
</div>
</div>
</form>
<div class="posts gap-3">
<div class="card w-100 bg-light mt-4 mb-4" v-for="(post, index) in $page.props.posts"
:key="post.id">
<div class="card-body" :data-id="post.id">
<h5 class="card-title">{{ post.request }}</h5>
<p class="card-text">{{ post.response }}</p>
<div class="buttons gap-3">
<a href="#" class="btn btn-outline-secondary btn-sm mx-2 copy"
@click.prevent="copyToClipBoard(post.response); copyBtn(index, $event)">
<i class="fa-regular fa-copy"></i>
{{ copyBtnText }}
</a>
<form @click.prevent="" method="POST">
<button type="submit" class="btn btn-outline-secondary btn-sm save"
@click.prevent="save(postID)">
<i class="fa-regular fa-heart"></i> Save</button>
<input type="hidden" name="postId" id="postId" :value="post.id">
</form>
</div>
</div>
</div>
</div>
Javascript
import { defineComponent } from "vue"
import { reactive } from 'vue'
import AppLayout from "@/Layouts/AppLayout.vue"
export default defineComponent({
components: {
AppLayout
},
props: ['errors'],
data() {
return {
form: {
inputText: null,
},
copyBtnText: 'Copy',
postID: 7
}
},
methods: {
post(data) {
this.$inertia.post('/post', data)
},
save(s) {
this.$inertia.post('/save', s)
},
copyToClipBoard(textToCopy) {
navigator.clipboard.writeText(textToCopy);
},
copyBtn(index, e) {
// this.copyBtnText = 'Copied!'
e.target.innerText = 'Copied!'
}
}
});