nI try to fetch some userdata from a mongodb (json format) using axios.get within an vue.js application. After this, i want to visualize this data using a iteration through all user-objects within the users array. But my problem is, that every single character is a single object in this array. What i want is, that every single user-json file is one object in this array. If i have three user-objects user.length should be three.
Here the code for the axios call:
axios
.get(RL + "/users")
.then(response => {
this.users = response.data
})
.catch(e => {
this.errors.push(e);
console.log("Errors in Users: " + e);
});
And with this snipped i want to iterate through all objects, displaying the username. But user.name is always only a single character and not the whole name.
<div v-if="users">
<li v-for="user in users">
{{user.name}}
</li>
</div>
Without any plugin.
var app = new Vue({
el: '#app',
// YOUR DATA HERE
data: {
filterResult: [] // THIS IS YOUR JSON FILE
},
// READY FUNCTION HERE
created: function() {
this.filterResult = this.dataResult();
},
// YOU FUNCTION HERE
methods: {
// CALLING API
dataResult: function() {
$.getJSON('/api/feature/stores/list', function(json) {
app.results = json;
app.filterResult = json;
});
},
}
});
Related
I'm new in VueJs, actually coming from react, the problem I'm having is that when i fetch the data with an axios.get the console.log shows a succesfull response. But when I to iterate through the Array with v-for it renders nothing.
It's quite important so it be super appreciated if you can tell me what im doing wrong or you have a suggestion.
heres the code:
<SignUpForm />
<h1>Countries List</h1 >
<div v-for="country in countries" :key="country.name" >
<p>{{country.name}}</p>
</div>
</template>
<script>
import SignUpForm from "#/components/SignUpForm.vue";
import axios from 'axios'
export default{
name: 'SignUpView',
components:{
SignUpForm
},
data(){
return{
countries: []
}
},
async mounted() {
const {data} = await axios.get('https://gist.githubusercontent.com/keeguon/2310008/raw/bdc2ce1c1e3f28f9cab5b4393c7549f38361be4e/countries.json')
console.info(data)
this.countries = data
}
}
</script>
You can see that what I'm actuallt doing is the axios.get in the mounted(){} f(x), later I = the data to my empty Array declared in data(){}. => So I can iterate trough the json response with a v-for in a div.
Heres the picture so you can see:
Observations :
countries list is a string and v-for is work if the input data is an array.
No. of objects in an array is 243 but this 9251 is a count of characters in a string.
Also, if we will try to convert that into a JSON object via JSON.parse() getting SyntaxError: Unexpected token n in JSON at position 6.
new Vue({
el: "#app",
data: {
countries: []
},
methods: {
getData() {
var vm = this;
axios.get("https://gist.githubusercontent.com/keeguon/2310008/raw/bdc2ce1c1e3f28f9cab5b4393c7549f38361be4e/countries.json")
.then(function(response) {
console.log(typeof response.data); <---- string
console.log(response.data.length); <---- actual objects in an array is 243 but this 9251 is a count of characters in a string.
console.log(JSON.parse(response.data)); <---- SyntaxError: Unexpected token n in JSON at position 6
})
.catch(function(error) {
alert(error);
});
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<div id="app">
<button #click="getData">Click to check Api response</button>
</div>
Hi I'm using Vuejs to get some pokemon data. So I figured out how to retrieve all the pokemon name and their api urls to get more information about them. The issue is I don't know how to take those URLs and access each pokemon's specific data. I tried to increment a variable and concatenate it to the URL to get their data but it didn't work. I also tried to access the data from the api call I already but that also didn't work.
<template>
<div>
<h2>{{subtitle}}</h2>
<div v-for="pokemon in basicInfo" v-bind:key="pokemon.name">
<span>{{ pokemon.name}}</span>
</div>
<!-- Nothing is produced, and I dont get I an error -->
<div v-for="pokemon2 in advInfo" v-bind:key="pokemon2.index">
<span>{{pokemon2}}</span>
</div>
<script>
import axios from "axios";
export default {
data() {
return {
subtitle: "First 150 pokemon",
basicInfo: [],
advInfo:[],
i:0
};
},
methods: {
// trying to increment i
getNext: function(){
this.i=i++;
}
},
mounted() {
axios
// this gets a list of the first 20 pokemon. I can get the pokemon's name and their url
.get("https://pokeapi.co/api/v2/pokemon/")
.then(response => {
this.basicInfo = response.data.results;
});
// here I'm trying to access more specific data on each pokemon by concatenating a number to the url
axios
.get("https://pokeapi.co/api/v2/pokemon/5")
.then(response => {
this.advInfo= response.data.results;
});
}
};
</script>
<style scoped>
</style>
It looks like ".../api/v2/pokemon/" produces an object with a results array, and those results contain uri's like ".../api/v2/pokemon/(some id)"
The way to combine them is as follows:
axios.get("https://pokeapi.co/api/v2/pokemon/").then(response => {
this.basicInfo = response
let promises = this.basicInfo.map(result => {
return axios.get(result.url)
})
Promise.all(promises).then(response => {
this.advInfo = response
})
});
Now advInfo will be an array, like you expect so you can render it with v-for....
<div v-for="(pokemon2, i) in advInfo" :key="i">
<pre>{{pokemon2}}</pre>
</div>
I'm trying to accomplish the following but I don't even know if it is even possible with Vue as I'm struggling to get the desired result:
I have an endpoint for an API which returns many objects within an array.
I am successfully rendering the data within my Vue application but I wanted to know if it is possible for Vue to "track" when the array has been updated with more objects and then render those in the view.
I am using setInterval to perform a GET request every 10 minutes and the new data is going into the object within my data() correctly but the changes are not reflected within the view.
At the moment I am changing a boolean from true to false at the beginning and end respectively so that the view is rendered again with v-if.
My goal is to create a simple Twitter feed app that performs a GET request every 10 minutes, collects the tweets, puts them into my Vue instance and show them in the view without having to reload the page/re-render the component. Like an automatic Twitter feed that just constantly loads new tweets every 10 minutes.
Is this even possible? I've tried using the Vue.set() method but that hasn't made any difference.
If it's not possible, what would be the best way to implement something similar?
Here is my code:
JavaScript:
new Vue({
el: '#app',
data: {
items: [],
},
created() {
this.load();
setInterval(() => this.load(), 5000);
},
methods: {
load() {
axios.get('https://reqres.in/api/users?page=2')
.then(response => {
this.items = response.data.data;
});
}
}
});
HTML
<div id="app">
<p v-for="item in items">
{{ item.first_name }}
</p>
</div>
CodePen: https://codepen.io/tomhartley97/pen/VwZpZNG
In the above code, if the array is updated by the GET request, the chances are not reflected within the view?
Yes it is possible. The way you need to set new reactive properties in your Vue instance is the following:
For Object properties: Vue.set(this.baseObject, key, value)
The baseObject cannot be a Vue instance or the base data() object, so you will have to declare a container property.
For Array entries use native array methods: e.g. Array.prototype.push().
Using Vue.set(array, arrayIndex, newArrayElement) does not work
Hence, your solution might look something line that:
<script>
export default {
data() {
return {
response: [],
};
},
mounted() {
setInterval = (() => this.getData), 600000);
}
methods: {
async getData() {
const res = await request();
const resLength = res.data.length;
for (let i = 0; i < resLength; i++) {
// check if entry is already in array
const entryExists = this.response.some((entry) => {
return entry.id === res.data[i].id
})
if (!entryExists) {
// this will make the array entries responsive, but not nested Objects
this.response.push(res.data[i]);
// to create nested responsive Objects you will have to set them explicitly
// e.g. Vue.set(this.response[this.response.indexOf(res.data[i])], nestedObjectKey, res.data[i].nestedObject)
}
}
}
}
};
</script>
Well, I view the codepen, I known why your view do not get update: the api response always return the same array!
Try to return different data.
The api returns an array, so the data defines
data() {
return {
array: [] // array that api returns
}
}
The template may look like this
<div v-for="item in array">
</div>
And the update methods
update() {
setInterval(async () => {
let resp = await api()
this.array = resp.data.concat(this.array)
}, TEN_MINUTES)
}
I am trying to get data from json file, it has just json data.
[{"id":81,"body":"There are some reason to fix the issues","created_at":"2017-11-16 11:56:47","updated_at":"2017-11-16 11:56:47"}]
I added vue-resource and properly use it as per vue syntax.
import vueResource from 'vue-resource'
Vue.use(vueResource)
In my userlist component i am trying following script
export default {
data:function(){
return {
list:[],
car:{
id:'',
body:''
}
};
},
created: function(){
this.fetchCarList();
},
methods:{
fetchCarList: function(){
this.$http.get('http://localhost:8080/api.js').then(function(response){
this.list = response.data
});
}
}
}
And this is component HTML loop
<ul id="example-1">
<li v-for="item in list">
{{ item.body }}
</li>
</ul>
I have checked http://localhost:8080/api.js which is properly returning the data. Also when I am adding the json data in fetchCarList method then loop works fine but with get() call it does not working.
How can I solve the issue?
You have a scoping issue: this within the callback does not refer to your Vue instance. That is because you are not using ES6 arrow function, i.e.:
this.$http.get('http://localhost:8080/api.js').then(response => {
this.list = response.data
});
...which means the outer this is not passed in. You will have to proxy that yourself, i.e. var self = this on the outside, and then use self.list = response.data:
var self = this;
this.$http.get('http://localhost:8080/api.js').then(response => {
self.list = response.data
});
Hi guys I am using Vue JS to try and loop through my data. Here is my whole JS file:
var contentful = require('contentful');
var client = contentful.createClient({
space: 'HIDDEN',
accessToken: 'HIDDEN'
});
Vue.component('careers', {
template: '<div><div v-for="career in careerData">{{ fields.jobDescription }}</div></div>',
data: function() {
return {
careerData: []
}
},
created: function() {
this.fetchData();
},
methods: {
fetchData: function() {
client.getEntries()
.then(function (entries) {
// log the title for all the entries that have it
entries.items.forEach(function (entry) {
if(entry.fields.jobTitle) {
this.careerData = entries.items;
}
})
});
}
}
});
var app = new Vue({
el: '#app'
});
I am using methods to access some data from Contentful, once it has grabbed the necessary data it is sent to my data object.
If I console.log(careerData); within my console the following data is returned:
So I'd expect if I used v-for within my template and tried iterating over careerData it would render correctly however on my front-end I am left with an empty div like so:
<div id="app"><div></div></div>
I am currently pulling my component into my HTML like so:
<div id="app">
<careers></careers>
</div>
No errors are displayed within my console, can you think of any reason this might be happening?
Thanks, Nick
Several problems I think. As #dfsq said, you should use a arrow function if you want to keep context (this).
fetchData: function() {
client.getEntries()
.then(entries => {
this.careerData = entries.items
});
}
Then you may replace {{fields.jobDescription}} by {{career.fields.jobDescription}}, as #unholysheep wrote.
It may work. If it does not, you could add a this.$forceUpdate(); right after this.fetchData();
Use arrow function in forEach callback so you don't loose context:
fetchData: function() {
client.getEntries()
.then(entries => {
this.careerData = entries.items
});
}