Pushing ajax data to vue component - ajax

Having the following vue component
<employee-times :employees="{{$employees}}" :supplies="{{$supplies}}" :commits="{{$commits}}" :times="{{$times}}"></employee-times>
where I render the passed props
<template>
<div>
<select class="form-control input" v-model="currentYear" #change="filter()">
<option v-for="option in yearsOptions" v-bind:value="option">
{{ option }}
</option>
</select>
<tr v-for="employee,key in _employees" v-if="commits[key]">
<td>{{ key }}</td>
<td>{{ employee[0].first_name }}</td>
<td>{{ employee[0].last_name }}</td>
<td>{{ employee[0].nick }}</td>
<td>{{ employee[0].role }}</td>
<td>{{ employee[0].skill }}</td>
<td v-for="n in 12">
<div v-if="_commits[key][n]">{{ _commits[key][n].hours }}</div>
<div v-else> </div>
</td>
</tr>
</div>
</template>
than I try to filter the ajax data on change but the data will not update
here is the script what I'm trying, but from method function I'm not able to push the new data to the template
<script>
export default {
name: 'employee-times',
props: ['supplies', 'times', 'commits', 'employees'],
components: {
},
created() {
axios.get('/api/v1/roles', {
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
}).then(response => {
th
is.roles = response.data
}).catch(error => {
})
this._times = this.times;
this._commits = this.commits;
this._supplies = this.supplies;
this._employees = this.employees;
},
data() {
return {
count: 0,
yearsOptions: [],
_employees: {},
_supplies: {},
_times: {},
_commits: [],
currentYear: null,
currentStatus: 1,
currentPosition: 0,
statusOptions: [
{'id': '1',
'text': 'Active'
}, {'id': '0',
'text': 'Inactive'
}],
currentSkillset: 'all',
skillsetOptions: [
{'id': 'all',
'text': 'All'
}, {'l1': 'l1',
'text': 'L1'
}, {'l1': 'l2',
'text': 'L2'
}, {'l1': 'l3',
'text': 'L3'
}, {'l1': 'l4',
'text': 'L4'
}, {'l1': 'l5',
'text': 'L5'
}],
status: {},
roles: {},
skillsets: {}
};
},
mounted() {
this.currentYear = moment().format('Y')
var from = moment().subtract('4', 'years').format('Y')
var to = moment().add('2', 'years').format('Y')
while (from <= to) {
this.yearsOptions.push(from);
from++;
}
},
watch: {
'_employees': function (val, oldVal) {
console.log('new: %s, old: %s', val, oldVal)
}
},
methods: {
commit() {
},
clear() {
},
months() {
return moment.monthsShort()
},
filter() {
var data = {
year: this.currentYear,
status: this.currentStatus,
position: this.currentPosition,
//skill: currentSkillset
}
axios.post('/api/v1/supply/track-times', data, {
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
}).then(response => {
this._employees = {}
this.$set(this, '_employees', JSON.parse(response.data.employees))
this.$set(this,'_times', JSON.parse(response.data.times))
this.$set(this,'_supplies', JSON.parse(response.data.supplies))
this.$set(this, '_commits', JSON.parse(response.data.commits))
}).catch(error => {
})
}
},
};
</script>
What i missed in this case?

There's a problem with v-for and tables (ref 'v-for with 2 every time') that requires a template wrapper.
See example CodePen.
<div id='app'>
<table>
<template v-for="(employee, key) in employees">
<tr>
<td>{{ employee.first_name }}</td>
<td>{{ employee.last_name }}</td>
</tr>
</template>
<table>
</div>
It also appears that you do need to remove the underscores (try changing employee to _employee in the codepen).

Remove the "_" prefix from your data properties, then it should work. Vue uses underscores for internal stuff, so best avoid using it (see https://v2.vuejs.org/v2/api/#data)

Related

How to make array checkbox to work in laravel blade with petite-vue?

I want to create checkboxes which trigger a vue function when a user checks them. These checkboxes are an array. The problem I have is when I check one of the checkboxes, it will check all of them instead of the one I want.
Here is the script in the blade file.
#foreach ($students as $item)
<tr>
<td>{{ $item->student->name }} {{ $item->student_id }}</td>
<td>
<input type="checkbox" value="1" v-model="store.status"
#change="onclick('{{ $schedule->id }}','{{ $item->student_id }}')" id="">
Present
</td>
</tr>
#endforeach
And here is petite-vue script
<script type="module">
import {
createApp, reactive
} from 'https://unpkg.com/petite-vue?module';
createApp({
store: {
status: [],
},
onclick(schedule_id, student_id)
{
const token = '{{ $token }}';
const config = {
headers: { Authorization: 'Bearer ' + token }
}
const data = {schedule_id: schedule_id, student_id: student_id, status: `${this.store.status}`}
axios.post(`http://localhost:10000/api/check-present`, data, config)
.then((result) => {
console.log(result.data);
$('#successModal').modal('show');
})
.catch((err) => {
console.log(err.response)
});
}
}).mount('#app');
I look forward to idea how to solve this problem. Thanks.

I need the data ,according to the type I send

My view blade that displays the data of all types but I need the specific type only, where i send it by ajax: "{{ route('taxonomies.json',type) }}".How do I send the type that I want from the given type?
<div class="table">
<table id="taxonomyTable">
<thead>
<tr>
<th>SN</th>
<th>Title</th>
<th>Parent</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
</table>
</div>
<div class="modal fade" id="quickModal" tabindex="-1" role="dialog" aria-labelledby="quickModal" aria-hidden="true">
</div>
<input type="hidden" id="type" value="{{ $type }}" />
and the js is:
<script>
$(document).ready(function () {
var type = $('#type').val();
$('#taxonomyTable').DataTable({
processing: true,
serverSide: true,
ajax: "{{ route('taxonomies.json') }}",
columns: [
{
data: 'id',
render: function (data, type, row) {
return '<strong> #' + data + '</strong>';
}
},
{
data: 'title', name: 'title',
render: function (data, type, row) {
return '<strong>' + data + '</strong>';
}
},
{
data: 'parent', name: 'parent',
render: function (data, type, row) {
return '<strong>' + data.title + '</strong>';
}
},
{
data: 'type', name: 'type',
render: function (data, type, row) {
return '<strong>' + data.type+ '</strong>';
}
},
{
data: 'status',
render: function (data, type, row) {
return data === 'Active' ? '<button class="btn btn-outline-success btn-update-status" data-id="' + row.id + '">Active</button>' : '<button class="btn btn-xs btn-outline-danger btn-update-status" data-id="' + row.id + '">Inactive</button>';
}
},
{data: 'action', name: 'action', orderable: false, searchable: false}
]
});
});
</script>
and my route is:
Route::get('/taxonomies/taxonomy-json/{type}', 'Admin\TaxonomyController#taxonomyJson')->name('taxonomies.json');
and my TaxonomyController has:
public function taxonomyJson()
{
$taxonomy = Taxonomy::with('parent')->toJson();
return DataTables::of($taxonomy)
->addIndexColumn()
->addColumn('action', function ($taxonomy) {
return '<div class="table-actions float-left">
<i class="ik ik-edit-2 green"></i>
<i class="ik ik-trash-2 red"></i>
</div>';
})->make();
}
The code mentioned above displays all of the types in the data but I only need the data of given type.Like my types are category, tag, videos,slider,etc and I need the data of types category only.
How can I fetch it?
Change You Input Hidden tag to which include whole route with it's parameters
<input type="hidden" id="type" value="{{ route('taxonomies.json', ['type' => $type]) }}" />
Now, In Your Ajax call pass input hidden type value directly to ajax as url.
var type_url = $('#type').val();
ajax: type_url
This way you don't have to worry about passing dynamic param. value to JS code from PHP code.
& In Your Controller Function
public function taxonomyJson($type=null)
{
$taxonomy = Taxonomy::with('parent')
if ($type) {
$taxonomy = $taxonomy->where('type', $type);
}
$taxonomy = $taxonomy->toJson();
return DataTables::of($taxonomy)
->addIndexColumn()
->addColumn('action', function ($taxonomy) {
return '<div class="table-actions float-left">
<i class="ik ik-edit-2 green"></i>
<i class="ik ik-trash-2 red"></i>
</div>';
})->make();
}
From your question as far I understood that you want filtered data, in order to get filtered data you needed to pass a filter type which you must use to filter your query. Here is an example for you
if ($request->ajax()) {
$users = User::select(
'users.id',
'users.name',
'users_details.first_name',
'users_details.last_name',
'users.email',
'users.membership_no',
'users.is_active',
'users.created_at'
)
->leftJoin('users_details', 'users.id', '=', 'users_details.users_id')
->where('user_group', '<>', 'admin')
->where(function ($query) use ($request) {
$genery = $request->get("genere");
$varsitySession = $request->get("varsity_session");
$yearOfPassing = $request->get("year_of_passing");
$department = $request->get("department");
$bloodGroup = $request->get("blood_group");
$membership = $request->get("membership");
if (isset($genery) && $genery) {
$query->where('users_details.genre', $genery);
}
if (isset($varsitySession) && $varsitySession) {
$query->where('users_details.varsity_session', $varsitySession);
}
if (isset($yearOfPassing) && $yearOfPassing) {
$query->where('users_details.year_of_passing', $yearOfPassing);
}
if (isset($department) && $department) {
$query->where('users_details.department', $department);
}
if (isset($bloodGroup) && $bloodGroup) {
$query->where('users_details.blood_group', $bloodGroup);
}
if (isset($membership) && $membership) {
$query->where('users_details.membership', $membership);
}
if (isset($request->requested) && $request->requested == 0) {
$query->where('users.membership_no', $request->requested);
}
})
->get();
return Datatables::of($users)
->editColumn('name', function ($users) {
return ($users->first_name) ? $users->first_name . ' ' . $users->last_name : $users->name;
})
->editColumn('is_active', function ($users) {
return ($users->is_active) ? 'Active' : 'De-active';
})
->editColumn('membership_no', function ($users) {
return ($users->membership_no) ? $users->membership_no : 'Not Assigned';
})
->editColumn('created_at', function ($users) {
return $users->created_at->toDayDateTimeString();
})
->make(true);
}
Here you can see that I'm generating a query with where clause which are generated from request data
$genery = $request->get("genere");
$varsitySession = $request->get("varsity_session");
$yearOfPassing = $request->get("year_of_passing");
$department = $request->get("department");
$bloodGroup = $request->get("blood_group");
$membership = $request->get("membership");
Here genere,varsity_session,year_of_passing,department,blood_group,membership are my filter data I'm sending with request.
here is my data table code
$('.dataTable').dataTable({
destroy: true,
paging: true,
searching: true,
sort: true,
processing: true,
serverSide: true,
"ajax": {
url: '{{ url('users/datatable')}}',
type: 'POST',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
'data': function (d) {
d.genere = $("#genere").val();
d.varsity_session = $("select[name = varsity_session]").val();
d.year_of_passing = $("select[name = year_of_passing]").val();
d.department = $("select[name = department]").val();
d.blood_group = $("input[name = blood_group]").val();
d.membership = $("select[name = membership]").val();
d.paymentStatus = $("select[name = paymentStatus]").val();
d.requested = $("select[name = requested]").val();
}
},
"columns": [
{data: 'id'},
{data: 'name'},
{data: 'email'},
{data: 'membership_no'},
{data: 'is_active'},
{data: 'varsity_session'},
{data: 'due_amount'},
{data: 'paid_amount'},
{data: 'created_at'},
{data: 'last_transaction_date'},
{data: 'action'},
],
"columnDefs": [
{"bSortable": false, "targets": [1, 6]},
{"searchable": false, "targets": [4, 6]}
],
lengthMenu: [[10, 50, 100, -1], [10, 50, 100, "All"]],
pageLength: 10,
"dom": 'Blfrtip',
buttons: [
{
extend: 'copy',
text: 'copy',
className: 'btn btn-primary',
exportOptions: {
columns: 'th:not(:last-child)'
}
},
{
extend: 'csv',
text: 'csv',
className: 'btn btn-warning',
exportOptions: {
columns: 'th:not(:last-child)'
}
},
{
extend: 'excel',
text: 'excel',
className: 'btn btn-danger',
exportOptions: {
columns: 'th:not(:last-child)'
}
},
{
extend: 'pdf',
text: 'pdf',
className: 'btn btn-success',
exportOptions: {
columns: 'th:not(:last-child)'
}
},
{
extend: 'print',
text: 'print',
className: 'btn btn-btn-info',
exportOptions: {
columns: 'th:not(:last-child)'
}
}
]
});
});
And my Static Html code
<div class="row">
<div class="col-lg-12">
<div class="table-responsive">
<table class="display compact dataTable">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Membership No</th>
<th>Status</th>
<th>Versity Session</th>
<th>Due Amount</th>
<th>Paid Amount</th>
<th>Created At</th>
<th>Last Transaction</th>
<th>Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<!-- /.col-lg-12 -->
</div>

How to use vuetify's custom sort?

I'd like to use custom-sort in my data table. My goal is to sort the table DESC as opposed to the default ASC. But I don't know-how.
This is the start of my data table component:
<v-data-table
:headers="headers"
:items="acts"
hide-actions
class="elevation-1"
>
<template slot="items" slot-scope="props">
<td>{{ props.item.id }}</td>
<td>{{ props.item.name }}</td>
<td class="text-xs-center">{{ props.item.provider.id }}</td>
<td class="text-xs-center">{{ props.item.category.name }}</td>
<td class="text-xs-center">{{ props.item.budget }}</td>
<td class="text-xs-center">{{ props.item.location.name }}</td>
<td class="text-xs-center">{{ props.item.deets }}</td>
<td class="text-xs-center">{{ props.item.keeping_it_100 }}</td>
<td class="text-xs-center"><img width="50" height="50" :src="props.item.inspiration.inspiration"></td>
<td class="justify-center layout px-0">....
And this is the script I'm using:
<script>
export default {
data () {
return {
dialog: false,
customerSort: {
isDescending: true,// I tried this? as the kabab format throws an error
},
headers: [
{ text: 'ID', value: 'id'},
{ text: 'Name', value: 'name' },
{ text: 'Provider', value: 'provider' },
{ text: 'Category', value: 'category' },
{ text: 'Budget', value: 'budget' },
{ text: 'Country', value: 'location', sortable: true },
{ text: 'Keeping it 100%', value: 'keeping_it_100', sortable: false },
{ text: 'deets', value: 'deets', sortable: false },
{ text: 'inspiration', value: 'inspiration', sortable: false },
{ text: 'Cover', value: 'cover', sortable: false },
{ text: 'Actions', value: 'actions', sortable: false }
],
According to docs it is a function prop. But I haven't found an example on how to pass it.
This is a screenshot of the function...
You can use a function like this-
customSort(items, index, isDesc) {
items.sort((a, b) => {
if (index === "date") {
if (!isDesc) {
return compare(a.date, b.date);
} else {
return compare(b.date, a.date);
}
}
});
return items;
}
Where the compare is a function which compares a.date and b.date and returns 1 or -1
isDesc is a variable passed by the table which tells in what order does the user want to sort it. If you want to sort in desc, just use !isDesc in the if-else condition
To use this in your template just use
<v-data-table
:headers="headers"
:items="Data"
:custom-sort="customSort"
>
<template slot="items" slot-scope="props">
<td class="font-weight-black">{{ props.item.date }}</td>
<td class="text-xs-right">{{ props.item.time }}</td>
<td class="text-xs-right">{{ props.item.name }}</td>
</template>
</v-data-table>
To make sure your other fields still work with the normal sort use
customSort(items, index, isDesc) {
items.sort((a, b) => {
if (index === "date") {
if (!isDesc) {
return dateHelp.compare(a.date, b.date);
} else {
return dateHelp.compare(b.date, a.date);
}
} else {
if (!isDesc) {
return a[index] < b[index] ? -1 : 1;
} else {
return b[index] < a[index] ? -1 : 1;
}
}
});
return items;
}
Although it's an old question ...
For special sorting of only one column, you could use the property sort in the headers array.
See also https://vuetifyjs.com/en/api/v-data-table/#headers
Like so:
// in data ...
headers: [
...
{
text: "Date",
sortable: true,
value: "date",
sort: (a, b) => a.time_stamp - b.time_stamp
},
...
]
use it like
<v-data-table
:headers="headers"
...
>
Based on this answer code about custom-filter, I tried using custom-sort.
Please refer to this answer if you apply it to your code.
By the following code, I have confirmed sorting when I click 'Calories' header.
My CodePen
new Vue({
el: '#app',
data() {
return {
food: [
{ name: 'Bakchoi', type: 'vegetable', calories: 100 },
{ name: 'Pork', type: 'meat', calories: 200 },
{ name: 'Chicken Thigh', type: 'meat', calories: 300 },
{ name: 'Watermelon', type: 'fruit', calories: 10 },
],
headers: [
{ text: 'Name', align: 'left', value: 'name' },
{ text: 'Food Type', align: 'left', value: 'type' },
{ text: 'Calories', align: 'left', value: 'calories' },
],
search: '',
};
},
methods: {
customSort(items, index, isDescending) {
// The following is informations as far as I researched.
// items: 'food' items
// index: Enabled sort headers value. (black arrow status).
// isDescending: Whether enabled sort headers is desc
items.sort((a, b) => {
if (index === 'calories') {
if (isDescending) {
return b.calories - a.calories;
} else {
return a.calories - b.calories;
}
}
});
return items;
}
}
})
<script src="https://unpkg.com/vue#2.4.2/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify#0.15.2/dist/vuetify.js"></script>
<link rel="stylesheet" href="https://unpkg.com/vuetify#0.15.2/dist/vuetify.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons">
<div id="app">
<v-app>
<v-select
label="Food Type"
:items="['vegetable', 'meat', 'fruit']"
v-model="search"
></v-select>
<v-data-table
:headers="headers"
:items="food"
:search="search"
:custom-sort="customSort"
hide-actions
>
<template slot="items" scope="{ item }">
<td>{{ item.name }}</td>
<td>{{ item.type }}</td>
<td>{{ item.calories }}</td>
</template>
</v-data-table>
</v-app>
</div>
NOTE: the following answer is for Vuetify 1.5.x
A little late to the party here, if all you want to do is sort descending by a single field, then custom-sort it not what you want to use, you're better off using the :pagination.sync prop
Custom sort is used when you want to change the behaviour of the comparison function (e.g sorting based off the reverse or lowercase version of a string, or proper sorting of date strings in the format 'DD-MM-YYYY').
If you want to use the default descending functionality, use the :pagination.sync prop, like so:
<v-data-table
:headers="headers"
:items="acts"
:pagination.sync="pagination"
>
<template v-slot:items="props">...</template>
</v-data-table>
In your script, set pagination:
data () {
return {
pagination: {
sortBy: 'id', // The field that you're sorting by
descending: true
}
}
}
This specifies that you want the table to be initially sorted by descending id - id can be changed to any field name in the dataset.
It's worth noting that this only specifies the default behaviour, and if you have sorting enabled for your other headers, users can still sort the table by any field.
To Build on the response provided by bhaskar
I had to edit the last code sample to the following in order to work on vuetify 2.x. The code sorts the date columns by their epoch time which is stored under the time_stamp key. The code also allows the default sorting of numbers and strings (strings are sorted alphabetically)
customSort(items, index, isDesc) {
items.sort((a, b) => {
if (index[0] == "date") {
if (!isDesc[0]) {
return a.time_stamp - b.time_stamp;
} else {
return b.time_stamp - a.time_stamp;
}
} else if (!(isNaN(a[index[0]]))) {
if (!isDesc[0]) {
return (a[index[0]] - b[index[0]]);
} else {
return (b[index[0]] - a[index[0]]);
}
} else {
if (!isDesc[0]) {
return (a[index[0]] < b[index[0]]) ? -1 : 1;
} else {
return (b[index[0]] < a[index[0]]) ? -1 : 1;
}
}
});
return items;
}
In vuetify 2 just use sortBy="date" and update: sort-desc
<v-data-table
:headers="headers"
:items="acts"
:pagination.sync="pagination"
sortBy="date"
update: sort-desc
>

Retrieve data using axios vue.js

I retrieve data using axios in methods created () like this:
data() {
return {
filterBox: false,
color: [],
sortBy: null,
productType: [],
products: null,
productcolors: null,
categories: null,
active_el: 0,
isActive: false,
categories: null,
inputSearch: '',
}
},
created() {
axios.get('/admin/product_index_vue').then(response => {
this.products = response.data.products.data;
this.productcolors = response.data.productcolors;
this.categories = response.data.categories;
console.log(this.products.length);
}).catch((error) => {
alert("ERROR !!");
});
},
when checking using console.log the data is there :
Vue DevTools :
but when trying to check the mounted () function I get empty data
what is the cause of this problem?
what I really want is to create a filter, but when using this function the data will not appear :
computed: {
filteredProduct: function () {
if (this.products.length > 0) {
return this.products.filter((item) => {
return (this.inputSearch.length === 0 || item.name.includes(this.inputSearch));
});
}
}
},
HTML CODE :
<tr v-for="product in filteredProduct">
<td style="width:20px;">{{product.id}}</td>
<td class="table-img-product">
<img class="img-fluid" alt="IMG">
</td>
<td> {{ product.name }}</td>
<td style="display:none">{{product.product_code}}</td>
<td>{{ product.base_color }}</td>
<td>{{ product.category }}</td>
<td>{{ product.price }}</td>
<td>{{ product.stock }}</td>
<td>{{ product.status }}</td>
<td>
<button type="button" name="button" v-on:click="deleteProduct(product.id,product.product_color_id)">
<i class="fas fa-trash"></i>
</button>
</td>
</tr>
RESULT
app.js:36719 [Vue warn]: Error in render: "TypeError: Cannot read
property 'length' of null"
found in
---> at resources\assets\js\components\products\Product_index.vue
what causes this function to not work and no detected product data?
This is because the computed property will potentially be calculated before the response has been returned.
If your data properties are going to be an array then I would suggest defining them as an array from the beginning. In the data object change the properties to something like e.g.
products: [],
productcolors: [],
Alternatively, you can add an additional check to your computed property method:
filteredProduct: function () {
if (!this.products) {
return [];
}
return this.products.filter((item) => {
return (this.inputSearch.length === 0 || item.name.includes(this.inputSearch));
});
}
this is axios response ont wording
mounted: {
let self = this
axios.get('/admin/product_index_vue').then(response=>{
self.products=response.data.products.data;
self.productcolors =response.data.productcolors;
self.categories=response.data.categories;
console.log(self.products.length);
}).catch((error)=>{
alert("ERROR !!");
});
},

Can't get data in laravel vue

I try to show detail of my posts by slugs but data won't render. i just get my navbar and white page,
Code
controller
public function single($slug)
{
$post = Post::where('slug', $slug)->first();
return response()->json([
"post" => $post
], 200);
}
single.vue where i show my single post data
<template>
<div class="post-view" v-if="post">
<div class="user-img">
<img src="...." alt="">
</div>
<div class="post-info">
<table class="table">
<tr>
<th>ID</th>
<td>{{ post.id }}</td>
</tr>
<tr>
<th>Title</th>
<td>{{ post.title }}</td>
</tr>
<tr>
<th>Body</th>
<td>{{ post.body }}</td>
</tr>
</table>
<router-link to="/blog">Back to all post</router-link>
</div>
</div>
</template>
<script>
export default {
created() {
if (this.posts.length) {
this.project = this.posts.find((post) => post.slug == this.$route.params.slug);
} else {
axios.get(`/api/posts/${this.$route.params.slug}`)
.then((response) => {
this.post = response.data.post
});
}
},
data() {
return {
post: null
};
},
computed: {
currentUser() {
return this.$store.getters.currentUser;
},
posts() {
return this.$store.getters.posts;
}
}
}
</script>
vuex store.js
state: {
posts: []
},
getters: {
posts(state) {
return state.posts;
}
},
mutations: {
updatePosts(state, payload) {
state.posts = payload;
}
},
actions: {
getPosts(context) {
axios.get('/api/posts')
.then((response) => {
context.commit('updatePosts', response.data.posts);
})
}
}
Question
Why I can't get my post data? is there any mistake in my code?
................................................................................................................................................................................
You're calling /api/posts/${this.$route.params.slug}, which (by REST convention) returns ONE post object.
When setting your post (this.post = response.data.post) you should use response.data (without .post)

Resources