I am trying to make a post request via axios but getting this error: app.js:285 POST http://127.0.0.1:8000/concerts/1/orders 500 (Internal Server Error)
The order is being processed though (I see it coming is Stripe and database). Another problem is that redirect is not happening as window.location =/orders/${response.data.confirmation_number}; I just stay on the same page.
Any ideas what could go wrong here?
<template>
<div>
<div class="row middle-xs">
<div class="col col-xs-6">
{{ csrf_token}}
<div class="form-group m-xs-b-4">
<label class="form-label">
Price
</label>
<span class='form-control-static '>
${{ priceInDollars }}
</span>
</div>
</div>
<div class="col col-xs-6">
<div class="form-group m-xs-b-4">
<label class="form-label">
Qty
</label>
<input type="number" v-model="quantity" class="form-control">
</div>
</div>
</div>
<div class="text-right">
<button class="btn btn-primary btn-block"
#click="openStripe"
:class="{ 'btn-loading': processing }"
:disabled="processing"
>
Buy Tickets
</button>
</div>
</div>
This is script part:
<script>
export default {
props: [
'price',
'concertTitle',
'concertId',
],
data() {
return {
quantity: 1,
stripeHandler: null,
processing: false,
}
},
computed: {
description() {
if (this.quantity > 1) {
return `${this.quantity} tickets to ${this.concertTitle}`
}
return `One ticket to ${this.concertTitle}`
},
totalPrice() {
return this.quantity * this.price
},
priceInDollars() {
return (this.price / 100).toFixed(2)
},
totalPriceInDollars() {
return (this.totalPrice / 100).toFixed(2)
},
},
methods: {
initStripe() {
const handler = StripeCheckout.configure({
key: App.stripePublicKey
})
window.addEventListener('popstate', () => {
handler.close()
})
return handler
},
openStripe(callback) {
this.stripeHandler.open({
name: 'TicketBeast',
description: this.description,
currency: "usd",
allowRememberMe: false,
panelLabel: 'Pay {{amount}}',
amount: this.totalPrice,
// image: '/img/checkout-icon.png',
token: this.purchaseTickets,
})
},
purchaseTickets(token) {
this.processing = true
axios.post(`/concerts/${this.concertId}/orders`, {
email: token.email,
ticket_quantity: this.quantity,
payment_token: token.id,
}).then(response => {
window.location =`/orders/${response.data.confirmation_number}`;
console.log('Charge succeeded.')
}).catch(response => {
this.processing = false
})
}
},
created() {
this.stripeHandler = this.initStripe()
}
}
You have to go and look under the Network tab if you are using Chrome browser, you can see the failed request response
The issue turns out to be Mailer. In .env file, along with Mailtrap credentials you must provide sender email and they don't tell you that :( This also somehow prevented the redirect. In case that helps someone.
Related
I had the following code and everything was working as expected.
<template>
<div id="login">
<form #submit.prevent="submit">
<p class="loading" :class="{ hideLoad: !loading }">Loading...</p>
<label for="email">Email</label>
<input type="text" id="email" v-model="fields.email" />
<span v-if="errors && errors.email" class="error">{{
errors.email[0]
}}</span>
<label for="password">Password</label>
<input type="password" id="password" v-model="fields.password" />
<span v-if="errors && errors.password" class="error">{{
errors.password[0]
}}</span>
<button type="submit">Log In</button>
<span
>Don't have an account?
<router-link :to="{ name: 'Register' }">Sign Up</router-link></span
>
</form>
</div>
</template>
<script>
export default {
data() {
return {
fields: {},
errors: {},
loading: false,
};
},
methods: {
submit() {
this.loading = true;
axios
.post("/api/login", this.fields)
.then((res) => {
if (res.status == 201) {
localStorage.setItem("authenticated", "true");
this.$router.push({ name: "Dashboard" });
}
})
.catch((error) => {
if (error.response.status == 422) {
this.errors = error.response.data.errors;
this.loading = false;
}
});
},
},
};
</script>
I then decided to use pinia to manage state and came up with the following.
<template>
<div id="login">
<form #submit.prevent="loginStore.submit">
<p class="loading" :class="{ hideLoad: !loginStore.loading }">Loading...</p>
<label for="email">Email</label>
<input type="text" id="email" v-model="loginStore.fields.email" />
<span v-if="loginStore.errors && loginStore.errors.email" class="error">{{
loginStore.errors.email[0]
}}</span>
<label for="password">Password</label>
<input type="password" id="password" v-model="loginStore.fields.password" />
<span v-if="loginStore.errors && loginStore.errors.password" class="error">{{
loginStore.errors.password[0]
}}</span>
<button type="submit">Log In 2</button>
<span
>Don't have an account?
<router-link :to="{ name: 'Register' }">Sign Up</router-link></span
>
</form>
</div>
</template>
<script setup>
import {useLoginStore} from '../stores/login'
const loginStore = useLoginStore();
</script>
My login.js
import { defineStore } from 'pinia'
export const useLoginStore = defineStore('login', {
state: () => {
return {
fields: {},
errors: {},
loading: false,
}
},
actions: {
submit() {
this.loading = true;
axios
.post("/api/login", this.fields)
.then((res) => {
if (res.status == 201) {
localStorage.setItem("authenticated", "true");
this.$router.push({ name: "Dashboard" });
}
})
.catch((error) => {
if (error.response.status == 422) {
this.errors = error.response.data.errors;
this.loading = false;
}
});
},
},
})
Everything is working as before and the only error is that when I fill the form with the correct credential and submit then I get Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'status') at app.js
I've tried all I can and I just can't figure out what it is that I'm doing wrong.
After debugging it further, I realized the error was coming from this.$routerinstance since a user gets login successfully and the status code is okay when I console log.
The instance is available in components only https://router.vuejs.org/api/#component-injected-properties
So, I fixed the problem by importing router in the store.js file,
import router from '../router'
then I pushed to another route by just using
router.push({ name: "Dashboard" });
instead of this.$router.push({ name: "Dashboard" });
I have a list of nested comments. Under each comment, I'd like to add a "reply" button that, when click, show a reply form.
For now, everytime I click a "reply" button, it shows the form. But the thing is, I'd like to show only one form on the whole page. So basically, when I click on "reply" it should close the other form alreay opened and open a new one under the right comment.
Edit :
So I was able to make some slight progress. Now I'm able to only have one active form opening on each level of depth in the nested loop. Obviously, what I'm trying to do now is to only have one at all.
What I did was emitting an event from the child component and handle everything in the parent component. The thing is, it would work great in a non-nested comment list but not so much in my case...
Here is the new code:
In the parentComponent, I have a handleSelected method as such:
handleSelected (id) {
if(this.selectedItem === id)
this.selectedItem = null;
else
this.selectedItem = id;
},
And my childComponent:
<template>
<div v-if="comment">
<div v-bind:style=" iAmSelected ? 'background: red;' : 'background: none;' ">
<p>{{ comment.author.name }}<br />{{ comment.created_at }}</p>
<p>{{ comment.content }}</p>
<button class="button" #click="toggle(comment.id)">Répondre</button>
<button class="button" #click="remove(comment.id)">Supprimer</button>
<div v-show="iAmSelected">
<form #submit.prevent="submit">
<div class="form-group">
<label for="comment">Votre réponse</label>
<textarea class="form-control" name="comment" id="comment" rows="5" v-model="fields.comment"></textarea>
<div v-if="errors && errors.comment" class="text-danger">{{ errors.comment[0] }}</div>
</div>
<button type="submit" class="btn btn-primary">Envoyer</button>
<div v-if="success" class="alert alert-success mt-3">
Votre réponse a bien été envoyée !
</div>
</form>
</div>
</div>
<div v-if="comment.hasReply">
<div style="margin-left: 30px;">
<comment v-for="comment in comments"
:key="comment.id"
:comment="comment" #remove-comment="remove"
:is-selected="selectedItem" #selected="handleSelected($event)">
</comment>
</div>
</div>
</div>
</template>
<script>
import comment from './CommentItem'
export default {
name: 'comment',
props: {
isSelected: Number,
comment: {
required: true,
type: Object,
}
},
data () {
return {
comments: null,
fields: {},
errors: {},
success: false,
loaded: true,
selectedItem: null,
}
},
computed: {
iAmSelected () {
return this.isSelected === this.comment.id;
}
},
methods: {
remove(id) {
this.$emit('remove-comment', id)
},
toggle(id) {
this.$emit('selected', id);
},
handleSelected(id) {
if(this.selectedItem === id)
this.selectedItem = null;
else
this.selectedItem = id;
},
},
mounted(){
if (this.comment.hasReply) {
axios.get('/comment/replies/' + this.comment.id)
.then(response => {
this.comments = response.data
})
}
}
}
</script>
Thanks in advance for your help!
My page exist of a table where I can add new rows. If you want to add a new row a pop-up window appear where the new values can be added.
This new data is then saved to the database after submitting. If I again want to add a new row the input fields, they should be cleared.
The method I use, is working but isn't very clear.
Note: My code shows only a part of the input fields, to make it more clear. My pop-up window actually contains 20 input fields.
I would like to clear them all at once instead of clearing them one by one (like I am doing now).
Because I am already doing this for defining the v-model, pushing the new data to the database directly on the page and via post axios request.
Is there a cleaner way to do this?
Thanks for any input you could give me.
This is my code:
html part
<div class="col-2 md-2">
<button class="btn btn-success btn-sx" #click="showModal('add')">Add New</button>
<b-modal :ref="'add'" hide-footer title="Add new" size="lg">
<div class="row" >
<div class="col-4">
<b-form-group label="Category">
<b-form-input type="text" v-model="newCategory"></b-form-input>
</b-form-group>
</div>
<div class="col-4">
<b-form-group label="Name">
<b-form-input type="text" v-model="newName" placeholder="cd4"></b-form-input>
</b-form-group>
</div>
<div class="col-4">
<b-form-group label="Amount">
<b-form-input type="number" v-model="newAmount" ></b-form-input>
</b-form-group>
</div>
</div>
<div class="row" >
<div class="col-8">
</div>
<div class="col-4">
<div class="mt-2">
<b-button #click="hideModal('add')">Close</b-button>
<b-button #click="storeAntibody(antibodies.item)" variant="success">Save New Antibody</b-button>
</div>
</div>
</div>
</b-modal>
</div>
js part
<script>
import { async } from 'q';
export default {
props: ['speciedata'],
data() {
return {
species: this.speciedata,
newCategory: '',
newName: '',
newAmount:'',
}
},
computed: {
},
mounted () {
},
methods: {
showModal: function() {
this.$refs["add"].show()
},
hideModal: function(id, expId) {
this.$refs['add'].hide()
},
addRow: function(){
this.species.push({
category: this.newCategory,
name: this.newName,
amount: this.newAmount,
})
},
storeSpecie: async function() {
axios.post('/specie/store', {
category: this.newCategory,
name: this.newName,
amount: this.newAmount,
})
.then(this.addRow())
// Clear input
.then(
this.newName = '',
this.newCategory = '',
this.newAmount = '',
)
.then(this.hideModal('add'))
},
}
}
</script>
in your data of vuejs app , you have to set one object for displaying modal data like modalData then to reset data you can create one function and set default value by checking type of value using loop through modalData object keys
var app = new Vue({
el: '#app',
data: {
message:"Hi there",
modalData:{
key1:"value1",
key2:"value2",
key3:"value3",
key4:5,
key5:true,
key6:"val6"
}
},
methods: {
resetModalData: function(){
let stringDefault="";
let numberDefault=0;
let booleanDefault=false;
Object.keys(this.modalData).forEach(key => {
if(typeof(this.modalData[key])==="number"){
this.modalData[key]=numberDefault;
}else if(typeof(this.modalData[key])==="boolean") {
this.modalData[key]=booleanDefault;
}else{
// default type string
this.modalData[key]=stringDefault;
}
});
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
{{modalData}}
<br/>
<button #click="resetModalData">Reset Modal Data</button>
</div>
update : in your case :
data:{
species: this.speciedata,
modalData:{
newCategory: '',
newName: '',
newAmount:''
}
},
and after storing data :
storeSpecie: async function() {
axios.post('/specie/store', {
category: this.newCategory,
name: this.newName,
amount: this.newAmount,
})
.then(()=>{
this.addRow();
this.resetModalData();
this.hideModal('add')
}
},
In native Javascript you get the reset() method.
Here is how it is used :
document.getElementById("myForm").reset();
It will clear every input in the form.
I'm trying to submit a form request using axios, have it validated, and return errors if the validation fails. The problem is, when I submit the form, no error messages are returned for me to show on the client side. Here's the HTTP request and vue component:
<div class="card">
<div class="card-header">
<h4>Information</h4>
</div>
<div class="card-body">
<p v-if='!isEditMode'><strong>Name:</strong> {{businessData.name}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-name">Name</label></strong>
<input class="form-control" name="business-name" v-model='businessData.name'>
</div>
<p v-if='!isEditMode'><strong>Description:</strong> {{businessData.description}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-description">Description</label></strong>
<textarea class="form-control normal" name="business-description"
placeholder="Enter your services, what you sell, and why your business is awesome"
v-model='businessData.description'></textarea>
</div>
</div>
</div>
<div class="card">
<h4 class="card-header">Address Information</h4>
<div class="card-body">
<p v-if="!isEditMode"><strong>Street Address: </strong> {{businessData.street}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-street">Street Address: </label></strong>
<input type="text" class="form-control" name="business-street" v-model='businessData.street' placeholder="1404 e. Local Food Ave">
</div>
<p v-if="!isEditMode"><strong>City: </strong> {{businessData.city}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-city">City: </label></strong>
<input class="form-control" type="text" name="business-city" v-model='businessData.city'>
</div>
<p v-if="!isEditMode"><strong>State: </strong> {{businessData.state}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-state">State: </label></strong>
<select class="form-control" name="business-state" id="state" v-model="businessData.state" >...</select>
</div>
<p v-if="!isEditMode"><strong>Zip: </strong> {{businessData.zip}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-zip">Zip: </label></strong>
<input class="form-control" type="text" maxlength="5" name="business-zip" v-model='businessData.zip'>
</div>
</div>
</div>
<div class="card">
<h4 class="card-header">Contact Information</h4>
<div class="card-body">
<p v-if="!isEditMode"><strong>Phone: </strong> {{businessData.phone}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-phone">Phone: </label></strong>
<input class="form-control" type="tel" name="business-phone" v-model='businessData.phone'>
</div>
<p v-if="!isEditMode"><strong>Email: </strong> {{businessData.email}}</p>
<div class="form-group" v-if='isEditMode'>
<strong><label for="business-Email">Email: </label></strong>
<input class="form-control" type="email" name="business-email" v-model='businessData.email'>
</div>
</div>
</div>
</div>
<script>
export default {
data () {
return {
isEditMode: false,
businessData: this.business,
userData: this.user,
errors: []
}
},
props: {
business: {},
user: {},
role: {}
},
//Todo - Institute client side validation that prevents submission of faulty data
methods: {
validateData(data) {
},
saveBusinessEdits () {
axios.put('/businesses/' + this.business.id , {updates: this.businessData})
.then(response => {
console.log(response.data)
// this.businessData = response.data;
this.isEditMode = false;
})
.catch (response => {
console.log(response.data)
this.isEditMode = false;
})
},
saveUserEdits () {
axios.put('/profile/' + this.user.id , {updates: this.userData})
.then(response => {
console.log(response.data)
this.userData = response.data;
this.isEditMode = false;
})
.catch (response => {
console.log(response)
this.isEditMode = false;
})
}
}
}
Route
Route::put('/businesses/{id}', 'BusinessesController#update');
BusinessController and update function
public function update(BusinessRequest $request, $id)
{
$business = Business::find($id)->update($request->updates);
$coordinates = GoogleMaps::geocodeAddress($business->street,$business->city,$business->state,$business->zip);
if ($coordinates['lat']) {
$business['latitude'] = $coordinates['lat'];
$business['longitude'] = $coordinates['lng'];
$business->save();
return response()->json($business,200);
} else {
return response()->json('invalid_address',406);
}
$business->save();
return response()->json($business,200);
}
and BusinessRequest class
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'business-name'=> 'required|string|max:255',
'business-description'=> 'required|string',
'business-phone' => 'nullable|phone|numeric',
'business-email' => 'nullable|email',
'business-street'=> 'required|string',
'business-city' => 'required|string',
'business-state' => 'required|string|max:2',
'business-zip' => 'required|min:5|max:5|numeric',
];
}
public function messages() {
return [
'business-zip.min:5' =>'your zip code must be a 5 characters long',
'business-email.email'=>'your email is invalid',
'business-phone.numeric'=>'your phone number is invalid',
];
}
}
I don't understand why, even if input valid data, it responds with a 422 response and absolutely no error messages. Since this is laravel 5.6, the 'web' middleware is automatic in all of the routes in the web.php file. So this isn't the problem. Could anyone help me normalize the validation behavior?
In Laravel a 422 status code means that the form validation has failed.
With axios, the objects that are passed to the then and catch methods are actually different. To see the response of the error you would actually need to have something like:
.catch (error => {
console.log(error.response)
this.isEditMode = false;
})
And then to get the errors (depending on your Laravel version) you would have something like:
console.log(error.response.data.errors)
Going forward it might be worth having a look at Spatie's form-backend-validation package
You can use Vue.js and axios to validate and display the errors. Have a route called /validate-data in a controller to validate the data.
app.js file:
import Vue from 'vue'
window.Vue = require('vue');
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
class Errors {
constructor() {
this.errors = {};
}
get(field) {
if (this.errors[field]) {
return this.errors[field][0];
}
}
record(errors) {
this.errors = errors;
}
clear(field) {
delete this.errors[field];
}
has(field) {
return this.errors.hasOwnProperty(field);
}
any() {
return Object.keys(this.errors).length > 0;
}
}
new Vue({
el: '#app',
data:{
errors: new Errors(),
model: {
business-name: '',
business-description: '',
business-phone: ''
},
},
methods: {
onComplete: function(){
axios.post('/validate-data', this.$data.model)
// .then(this.onSuccess)
.catch(error => this.errors.record(error.response.data.errors));
},
}
});
Make a route called /validate-data with a method in the controller, do a standard validate
$this->validate(request(), [
'business-name'=> 'required|string|max:255',
'business-description'=> 'required|string',
'business-phone' => 'nullable|phone|numeric',
'business-email' => 'nullable|email',
'business-street'=> 'required|string',
'business-city' => 'required|string',
'business-state' => 'required|string|max:2',
'business-zip' => 'required|min:5|max:5|numeric'
]
);
Then create your inputs in your view file, using v-model that corresponds to the vue.js data model fields. Underneath it, add a span with an error class (basic red error styling, for example) that only shows up if the errors exist. For example:
<input type="text" name="business-name" v-model="model.business-name" class="input">
<span class="error-text" v-if="errors.has('business-name')" v-text="errors.get('business-name')"></span>
Don't forget to include the app.js file in footer of your view file. Remember to include the tag, and run npm run watch to compile the vue code. This will allow you to validate all errors underneath their input fields.
Forgot to add, have a buttton that has #onclick="onComplete" to run the validate method.
I'm attempting to nest some components - ultimately I would like to have a component which displays Posts, with a PostItem component used to render each post. Inside the PostItem, I want a list of related comments, with CommentItem to render each comment. I have the posts displayed using the PostItem with no errors, but as soon as I add the Comments I get errors. So to simplify, I've pulled the CommentsList component out and I'm just trying to display it on the page, manually loading in all comments - it's an exact copy of PostsList, except with comment replacing post, but it generates an error:
[Vue warn]: Property or method "commment" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
found in
---> <Comment> at resources/assets/js/components/CommentItem.vue
<CommentsList> at resources/assets/js/components/CommentsList.vue
<Root>
CommentsList.vue
<template>
<div class="media-list media-list-divided bg-lighter">
<comment v-for="comment in comments"
:key="comment.id"
:comment="comment">
</comment>
</div>
</template>
<script>
import comment from './CommentItem'
export default {
components: { comment },
data: function() {
return {
comment: {
id: 1,
content: "",
edited: false,
created_at: new Date().toLocaleString(),
user: {
id: 1,
name: '',
}
},
comments: [
{
id: 1,
content: "",
edited: false,
created_at: new Date().toLocaleString(),
user: {
id: 1,
name: '',
}
}
]
};
},
created() {
this.fetchCommentsList();
},
methods: {
fetchCommentsList() {
axios.get('/api/comments').then((res) => {
//alert(JSON.stringify(res.data[0], null, 4));
this.comments = res.data;
});
},
createComment() {
axios.post('api/comments', {content: this.comment.content, user_id: Laravel.userId, vessel_id: Laravel.vesselId })
.then((res) => {
this.comment.content = '';
// this.comment.user_id = Laravel.userId;
// this.task.statuscolor = '#ff0000';
this.edit = false;
this.fetchCommentsList();
})
.catch((err) => console.error(err));
},
deleteComment(id) {
axios.delete('api/comments' + id)
.then((res) => {
this.fetchCommentsList()
})
.catch((err) => console.error(err));
},
}
}
</script>
CommentItem.vue
<template>
<div>
<a class="avatar" href="#">
<img class="avatar avatar-lg" v-bind:src="'/images/user' + comment.user.id + '-160x160.jpg'" alt="...">
</a>
<div class="media-body">
<p>
<strong>{{ commment.user.name }}</strong>
</p>
<p>{{ comment.content }}</p>
</div>
</div>
</template>
<script>
export default {
name: 'comment',
props: {
comment: {
required: true,
type: Object,
default: {
content: "",
id: 1,
user: {
name: "",
id: 1
}
}
}
},
data: function() {
return {
}
}
}
</script>
I'm pretty new to Vue - I've read so many tutorials and have been digging through the documentation and can't seem to figure out why its working for me with my PostsList component thats an exact copy. It also seems odd that I need both comment and comments in the data return - something that my working Posts version requires.
I'll drop in my working Posts components:
PostsList.vue
<template>
<div>
<div v-if='posts.length === 0' class="header">There are no posts yet!</div>
<post v-for="post in posts"
:key="post.id"
:post="post">
</post>
<form action="#" #submit.prevent="createPost()" class="publisher bt-1 border-fade bg-white">
<div class="input-group">
<input v-model="post.content" type="text" name="content" class="form-control publisher-input" autofocus>
<span class="input-group-btn">
<button type="submit" class="btn btn-primary">New Post</button>
</span>
</div>
<span class="publisher-btn file-group">
<i class="fa fa-camera file-browser"></i>
<input type="file">
</span>
</form>
</div>
</template>
<script>
// import CommentsManager from './CommentsManager.vue';
import post from './PostItem.vue';
export default {
components: {
post
},
data: function() {
return {
post: {
id: 1,
content: "",
edited: false,
created_at: new Date().toLocaleString(),
user: {
id: 1,
name: '',
}
},
posts: [
{
id: 1,
content: "",
edited: false,
created_at: new Date().toLocaleString(),
user: {
id: 1,
name: '',
}
}
]
};
},
created() {
this.fetchPostsList();
},
methods: {
fetchPostsList() {
axios.get('/api/posts').then((res) => {
//alert(JSON.stringify(res.data[0], null, 4));
this.posts = res.data;
});
},
createPost() {
axios.post('api/posts', {content: this.post.content, user_id: Laravel.userId, vessel_id: Laravel.vesselId })
.then((res) => {
this.post.content = '';
// this.post.user_id = Laravel.userId;
// this.task.statuscolor = '#ff0000';
this.edit = false;
this.fetchPostsList();
})
.catch((err) => console.error(err));
},
deletePost(id) {
axios.delete('api/posts' + id)
.then((res) => {
this.fetchPostsList()
})
.catch((err) => console.error(err));
},
}
}
</script>
PostItem.vue
<template>
<div class="box">
<div class="media bb-1 border-fade">
<img class="avatar avatar-lg" v-bind:src="'/images/user' + post.user.id + '-160x160.jpg'" alt="...">
<div class="media-body">
<p>
<strong>{{ post.user.name }}</strong>
<time class="float-right text-lighter" datetime="2017">24 min ago</time>
</p>
<p><small>Designer</small></p>
</div>
</div>
<div class="box-body bb-1 border-fade">
<p class="lead">{{ post.content }}</p>
<div class="gap-items-4 mt-10">
<a class="text-lighter hover-light" href="#">
<i class="fa fa-thumbs-up mr-1"></i> 0
</a>
<a class="text-lighter hover-light" href="#">
<i class="fa fa-comment mr-1"></i> 0
</a>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'post',
props: {
post: {
required: true,
type: Object,
default: {
content: "",
id: 1,
user: {
name: "",
id: 1
}
}
}
},
data: function() {
return {
}
}
}
</script>