Failed returning data from array - vue.js

i have a problem which that i cannot see the data inside array that i have pushed the data inside .then from axios
Here are the sample code
Axios from vue.js
export default {
name: 'facts',
data(){
const test = [{id: 'test',name: 'test'}]
const response = [];
const factsData = () => {
axios.get('http://localhost:3000').then(x=>response.push(x.data))
}
factsData();
console.log(response)
return{
test,
response
};
}
};
When i tried to console.log the output data inside the promise(.then) it worked well and display the data that i expected like this
and this is what happen when i tried to push the data from axios to response and show the output data in console.log with my current code above
when i tried to access it (console.log(response[0]), it shows undefined in console.log.
But strangely, when i back to my previous code to not to tried to access the data and i expand the array in console browser, it shows data that i expected which mean i couldn't access it.
The main purpose is i want to dipsplay the data to be rendered in table using v-for
<template>
<div class="about">
<center>
<table>
<thead>
<tr>
<th></th>
<th>ID</th>
<th>Username</th>
</tr>
</thead>
<tbody>
<tr v-for="(user,index) in test" :key="user.id">
<td>{{index + 1}}</td>
<td>{{user.id}}</td>
<td>{{user.name}}</td>
</tr>
</tbody>
</table>
</center>
</div>
</template>
Please tell me what i'm missing. Thank you.
P.S : I'm new to this vue js

your code structure is not correct. use this code:
export default {
name: 'ProfilePage',
data() {
return {
response: []
}
},
created () {
this.getData();
},
methods: {
getData() {
axios.get('http://localhost:3000').then(x => this.response = x.data);
}
}
}

Related

How can I get a result from a POST request into a v-for?

I have something like this:
<table class="table">
<tbody>
<tr v-for="(option, index) in Weapons">
<td>Primary</td>
<td>[[ getWeaponType(option.WeaponType) ]]</td>
</tr>
</tbody>
</table>
In my Vue object, in methods, I have this:
getWeaponType: function(weaponTypeNumber){
axios.get('/path/to/api')
.then(response => {
return response.data
})
}
I send an ID and it returns the name for that ID. But I need for it to show in my table whose rows are being generated by the v-for. This isn't working since it is a Promise and the values are not showing. Is there any way I can achieve getting that value to show in the table? I didn't want to do it server side so I'm trying to see if I have any options before I do that.
May I suggest an alternative method?
data() {
return {
weaponsMappedWithWeaponTypes: [];
}
}
mounted() { // I am assuming the weapons array is populated when the component is mounted
Promise.all(this.weapons.map(weapon => {
return axios.get(`/path/to/api...${weapon.weaponType}`)
.then(response => {
return {
weapon,
weaponType: response.data
}
})
).then((values) => {
this.weaponsMappedWithWeaponTypes = values
})
}
computed: {
weaponsAndTheirWeaponTypes: function () {
return this.weaponsMappedWithWeaponTypes
}
}
And then in your template
<table class="table">
<tbody>
<tr v-for="(option, index) in weaponsAndTheirWeaponTypes">
<td>Primary</td>
<td>option.weaponType</td>
</tr>
</tbody>
</table>

Vue in laravel 5.8, populate table dynamically from axios response

I have a blade where I'm using a multiselect as dropdown, and when a selection is chosen it fires off an axios call which returns a json_encoded data set.
The blade is here:
<div class="uk-width-1-2">
<multiselect
label="name"
track-by="value"
v-model="CategoryValue"
:options="CategoryOptions"
:multiple="false"
:taggable="true"
#tag="getItems"
#input="getItems"
#search-change="val => read(val)"
:preselect-first="false"
:close-on-select="true"
:preserve-search="true"
placeholder="Choose Category..."
></multiselect>
<div style="border:1px solid black; height:80%; margin-top:15px;">
<table>
<thead>
<tr>
<th>Text</th>
</tr>
</thead>
<tbody v-for="build in buildsList">
<tr>
<td>#{{ build.build_code_formatted }}</td>
</tr>
</tbody>
</table>
</div>
</div>
new Vue({
data() {
return{
buildsList: {},
}
},
methods: {
getItems() {
console.log(this.CategoryValue.value);
axios.post('/getItems',{
categoryCode: this.CategoryValue.value,
})
.then(function (response){
this.buildsList = response.data;
})
.catch(function (error) {
console.log(error);
});
}
}
})
And upon the callback I get a 200 and It does indeed log the buildsList so I know it is returning all of my data properly. However, when I get my data back in the console, it's not populating the html.
When I inspect the page elements there is no table body or data rows.
Also, my controller is returning this:
unction getItems(Request $request){
return json_encode($this->itemService->getItems($request->Code));
}
and itemService is doing this:
$results = $pdoStatement->fetchAll();
foreach ($results as &$r)
$r = (object) $r;
return $results;
So my data is coming back upon axios Call and it is formatted properly, but I just need to figure out why my table isn't dynamically populating
Please try to change this part
this.buildsList = response.data;
to
.then((response) => {
let data = response.data;
for (let key in data) {
if(data.hasOwnProperty(key)) {
this.$set(this.buildsList, key, data[key]);
}
}
})

Vuejs and datatables: table empty when using v-for to fill data

I'm trying to fill a datatable using vuejs v-for directive and ajax to get the data but the table is always showing "No data available in table" even though there are some data shown and also in the bottom says "Showing 0 to 0 of 0 entries". I guess this is because vuejs is reactive and the table can't recognize the changes maybe?
I've been searching and trying for a while but with no solution found..
thanks a lot! :)
here's the template:
<table id="suppliersTable" class="table table-hover table-nomargin table-bordered dataTable">
<thead>
<tr>
<th>...</th>
...
</tr>
</thead>
<tbody>
<tr v-for="supplier in suppliers">
<td>{{ supplier.Supplier_ID }}</td>
<td>...</td>
...
</tr>
</tbody>
</table>
and the vue and ajax:
<script>
export default {
data() {
return {
suppliers: [],
}
},
methods: {
fetchSuppliers() {
this.$http.get('http://localhost/curemodules/public/suppliers/list')
.then(response => {
this.suppliers = JSON.parse(response.bodyText).data;
});
}
},
created() {
this.fetchSuppliers();
},
}
Once initialized, DataTables does not automatically reparse the DOM. Here's a relevant FAQ:
Q. I append a row to the table using DOM/jQuery, but it is removed on redraw.
A. The issue here is that DataTables doesn't know about your manipulation of the DOM structure - i.e. it doesn't know that you've added a new row, and when it does a redraw it will remove the unknown row. To add, edit or delete information from a DataTable you must use the DataTables API (specifically the row.add(), row().data() and row().remove() methods to add, edit and delete rows.
However, you can call table.destroy() to destroy the current instance before reinitializing it. The key is to delay the reinitialization until $nextTick() so that Vue can flush the DOM of the old DataTables. This is best done from a watcher on suppliers so that the DataTables reinitialization is done automatically when the variable is updated in fetchSuppliers().
mounted() {
this.dt = $(this.$refs.suppliersTable).DataTable();
this.fetchSuppliers();
},
watch: {
suppliers(val) {
this.dt.destroy();
this.$nextTick(() => {
this.dt = $(this.$refs.suppliersTable).DataTable()
});
}
},
demo
I know this is a bit late answer but I just encountered this problem just today and my only solution for this issue is using setTimeout function.After fetching data using axios I set a bit of delay then init the data-table. With this work around v-for works fine.
See below for my code.
GetDepartmentList(){
axios.get('department')
.then((response) => {
this.departmentList = response.data;
// this.dataTable.rows.add(response.data).draw();
setTimeout(() => $('#department-data-table').DataTable(), 1000);
})
.catch((error) => {
if (error.response.status == 401) {
alert('User session has expired. Please login again.');
location.replace("/login");
}
});
},
Also you can use .rows.add() function if you want to draw row data in the table without using v-for of vue. Refer to this doc.
You can using Axios in Vuejs, you try see the following above:
<template>
<div class="danhsach">
<h2>{{title}}</h2>
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Password</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr v-for='data in datas'>
<td>{{data.id}}</td>
<td>{{data.name}}</td>
<td>{{data.password}}</td>
<td>{{data.age}}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default{
data(){
return {
title:"Tile Lists",
datas:[]
}
},
created:function(){
this.danhsach_user();
},
methods:{
danhsach_user(){
this.axios.get('https://599f807effe73c0011b9fcc5.mockapi.io/api/user').then((response)=>{
this.datas=response.data;
});
}
}
}
</script>

Vuejs class doesn't update after ajax request

What I'm trying to do is to highlight a table row after the component has been created or mounted. The playingTrack value is being changed to the id of the current song but the class doesn't change.
The #click function works and changes the class to highlight but what I want is for it to happen when component is mounted taking its value from playingTrack variable.
<tr :class="{highlight:track.id == playingTrack}" #click="playingTrack = track.id" v-for="track in tracks">
<td class="align-middle">
{{track.title}} <br> <span style="color: grey;">{{track.artist}}</span>
</td>
</tr>
<script>
export default{
data(){
return{
tracks:{},
album:{},
playingTrack: undefined
}
},
beforeCreate(){
Event.$emit('requestCurrentTrack');
Event.$on('currentTrack', (data) => this.fetchAlbum(data));
},
methods:{
fetchAlbum(data){
axios.get('/api/album/'+this.id).then((response)=>{
if(data){
this.playingTrack = data.id;
}
this.tracks = response.data[0];
this.album = response.data[1][0];
});
}
}
}
</script>
You can use "Computed Property"
https://v2.vuejs.org/v2/guide/computed.html
Here is well-written documentation.

Vue data referencing issue

This is strange because it was just working last night, but basically I have a Vue app that's pulling JSON from my backend. Code below. The strange part is that while the loadData function is running and I see the 'Loaded Data' message in console along with the list of items from the JSON, I then get a console error saying 'items is not defined'. I must have made a subtle typo or some dumb change but I can't find it anywhere!! Any ideas?
HTML snippet:
<div id="app">
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Query</th>
<th>Initiated By</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr>
<div v-for="item in items">
<td>{{ item.id }}</td>
<td>{{ item.query }}</td>
<td>{{ item.user }}</td>
<td>{{ item.type }}</td>
</div>
</tr>
</tbody>
</table>
</div>
</div>
(And then <script src="app.js"></script> right before </body>)
JS code:
new Vue({
el: '#app',
data: {
items: [],
interval: null
},
methods: {
loadData: function () {
$.get('http://localhost:4567/getQueue', function (response) {
this.items = response.results;
console.log("Loaded data.")
console.log(response.results)
}.bind(this));
}
},
created: function () {
console.log("Loading data...")
this.loadData();
console.log(items)
this.interval = setInterval(function () {
this.loadData();
}.bind(this), 3000);
},
beforeDestroy: function(){
clearInterval(this.interval);
}
});
You are getting the error
items is not defined
because of following line:
created: function () {
console.log("Loading data...")
this.loadData();
console.log(items) <== this should be console.log(this.items)
Turns out there was a few issues in my code.
1) As was pointed out by Saurabh, I forgot to put this.items instead of items.
2) this can't be referenced inside of the function I defined as I have it... instead, the function has to be defined with =>, for example:
$.get('http://localhost:4567/getQueue').then((response) => {
this.items = response.data.results;
console.log("loadData finished - items length is: "+this.items.length)
})
3) The big error I had was that my div bind with items was inside the table tag, which apparently isn't okay to do. Instead I applied the Vue binds to the existing tags (table, tr).