Vue.js i cant display fetched data - vue.js

Im fetching a feed with fetch, but somehow my vue app does not render it i have tried diffrent things but nothing seems to work for me.
<section id="vue-instagram" class="instagram">
<div class="instagram__col" v-for="item in feed">
<div class="instagram__col__picturebox">
<img v-if="item.media_url.indexOf('.mp4') == -1" v-bind:src="item.media_url"/>
<video v-if="item.media_url.indexOf('.mp4') > 0" loop preload muted controls style="width:100%;">
<source v-bind:src="item.media_url" />
</video>
</div>
<div class="instagram__col__description">
<div class="instagram__col__descroption--icon">
<img src="images/insta.png"/>
</div>
<div class="instagram__col__descroption--text">
{{item.caption.substring(0,90)}}...
<div class="hashtags bold-text">
{{item.caption.substring(item.caption.indexOf('#'), item.caption.length).split(' ').slice(0,5).join(' ')}}
</div>
</div>
</div>
</div>
</section>
var app = new Vue({
el: '#vue-instagram',
data:() => ({
loading: false,
feed: [],
}),
}, created: async () => {
var response = await fetch("URL_TOSERVER", {
method: "POST",
});
var {data} = await response.json();
this.feed = data;
console.log(data);
});
If I call this.feed in chrome it displays the data but if I drill into app.data its empty.

The solution was to extract the call as a method
new Vue({
el: '#vue-instagram',
data: {
loading: false,
feed: [],
},
created: function() {
this.fetchData();
},
methods: {
fetchData: function(){
var self = this;
fetch("http://727.dk.web81.curanetserver.dk/umbraco/api/instagram/index", {
method:"POST"
}).then(function(response){
return response.json();
}).then(function(data){
self.feed = data.data;
});
}
},
computed: {
posts: function() {
return this.feed;
}
}
});

Related

Cant store api data called by axios in array through mounted, unless clicking on <Root> element from vue devtools (in browser)

i'm using axios to get data from api and store in an array after mounting then run a search query in the array later on, but it's not working unless i click on Root element in browsers Vue developer tools, after i click on vue Root element from vue dev tool everything works fine.Here is my code..
<script type="module">
const vueApp = new Vue({
el: "#pos",
data: {
searchTerm: "",
allProducts: [],
selectedProducts: [],
suggestions: []
},
mounted: function (){
axios.get("api/products").then( res => this.allProducts = res.data );
},
methods: {
select(item){
this.selectedProducts.push(item);
this.suggestions = [];
}
},
computed:{
matches(){
if(!this.searchTerm) return;
this.suggestions = this.allProducts.filter(sP=>(sP.prod_name).includes(this.searchTerm));
}
}
});
</script>
//HTML below------------------
<div id="pos">
<input type="text" v-model="searchTerm">
<ul v-for="match in suggestions">
<li #click="select(match)">
{{match.prod_name}}
</li>
</ul>
<table>
<tr v-for="(product,i) in selectedProducts">
<td>#{{product.prod_name}}</td>
</tr>
</table>
</div>
const vueApp = new Vue({
el: "#pos",
data: {
searchTerm: "",
allProducts: [],
selectedProducts: [],
suggestions: []
},
mounted: function() {
axios.get("api/products").then(res => this.allProducts = res.data);
},
methods: {
select(item) {
this.selectedProducts.push(item);
this.suggestions = [];
}
},
computed: {
matches() {
if (!this.searchTerm) return;
this.suggestions = this.allProducts.filter(sP => (sP.prod_name).includes(this.searchTerm));
}
}
});
<div id="pos">
<input type="text" v-model="searchTerm">
<ul v-for="match in suggestions">
<li #click="select(match)">
{{match.prod_name}}
</li>
</ul>
</div>
As I mentioned in the comments on your question, this is an error I cannot seem to understand how you are getting. I sense there is information that we are not being presented with.
As such, here is a quick "working" example of fetching items from the mounted lifecycle hook in a component. Note: If you are creating the component via a Single-File Component (.vue files) then don't worry too much about the declaration, pay attention only to the data and mounted methods.
const App = Vue.component('App', {
template: `<div>
<input v-model="searchTerm" type="search">
{{items.length}} results fetched
</div>`,
data() {
return {
searchTerm: '',
items: []
}
},
mounted() {
//Timeout used to mimic axios query
setTimeout(()=> this.items= [1,2,3,4], 1000)
}
});
const app = new App({
el: '#app'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">Placeholder</div>
Edit
The code you have given us after your update seems to be working just fine. See the below snippet.
I noticed you are looping over suggestions but that value is never updated anywhere in your given code.
const vueApp = new Vue({
el: "#pos",
data: {
searchTerm: "",
allProducts: [],
selectedProducts: [],
suggestions: []
},
mounted: function() {
setTimeout(() => this.allProducts = [1,2,3,4,5], 1000);
},
methods: {
select(item) {
this.selectedProducts.push(item);
this.suggestions = [];
}
},
computed: {
matches() {
if (!this.searchTerm) return;
this.suggestions = this.allProducts.filter(sP => (sP.prod_name).includes(this.searchTerm));
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="pos">
<input type="text" v-model="searchTerm">
<ul v-for="match in suggestions">
<li #click="select(match)">
{{match.prod_name}}
</li>
</ul>
{{allProducts.length}} results loaded
</div>
mounted: function(){
var _self = this;
axios.get("api/products").then( res => _self.allProducts = res.data );
}

how to reverse message on clik button vue js

i want to reserve paragraph after click button
reserve paragraph is showing in second paragraph
for my case is i have to use template ?
here is my code
<div id="example">
<p>Original Message: "{{ message }}"</p>
<p id="pReserve"></p>
<button #click="reserve">Reserve</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.0"></script>
<script>
Vue.component('coba',{
});
var vm = new Vue({
el: '#example',
data: {
message: 'Hai'
},
computed: {
// a computed getter
reversedMessage: function () {
// `this` mengarah ke instance vm
return this.message .split('').reverse().join('')
}
},
methods: {
reserve:{
}
},
})
</script>
Here is the solution.
var vm = new Vue({
el: '#example',
data: {
message: 'Hai'
},
methods: {
reversedMessage: function() {
this.message = this.message.split('').reverse().join('');
}
},
});
<div id="example">
<p>Original Message: "{{ message }}"</p>
<p id="pReserve"></p>
<button #click="reversedMessage">Reserve</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.0"></script>

Move static parts of Vue code from methods() to <template>

Within my code there is some static data like const YAMAP_KEY and let src in the <script> section. I'd like to move those to the <template> section leaving the rest of the <script> section as is it now. How do I do it?
<template>
<div class='some-container container'>
<div id='yaMap'></div>
</div>
</template>
<script>
export default {
data: () => ({
}),
methods: {
loadYamap() {
return new Promise((resolve, reject) => {
const YAMAP_KEY = 'abcdef';
const YamapNode = document.createElement('script');
let src = 'https://api-maps.yandex.ru/2.1?lang=ru_RU&coordorder=longlat&apikey=' + YAMAP_KEY;
YamapNode.src = src;
YamapNode.onload = () => resolve();
YamapNode.onerror = (err) => {
console.log('map didn't load');
reject(err);
};
this.$el.appendChild(YamapNode);
});
}
},
mounted() {
this.loadYamap()
.then(() => {
ymaps.ready(() => {
var Yamap = new ymaps.Map('yaMap', {
center: [55.76, 37.64],
zoom: 10
})
})
})
.catch(ex => console.log('map load exception:', ex));
}
}
</script>
UP.
I've tried adding consts to the <template> section.
<template>
<div class='some-container container'>
<div id='yaMap'></div>
<script ref='myref'>
console.log('script in template');
const YAMAP_KEY = '8972y3uihfiuew';
let src = 'https://api-maps.yandex.ru/2.1?lang=ru_RU&coordorder=longlat';
<script>
</div>
</template>
Then accessing them in the <script> section.
<script>
export default {
data: () => ({
}),
methods: {
loadYamap() {
this.$refs.myref.onload = () => console.log('script in template loaded');
...
Add a tag inside and declare var for those constants and access them in your javascript code.
<div id="container">
<input type="text" id="container" placeholder="enter text" v-model="value">
<p>{{ value }}</p>
<script>var a = 'manu';</script>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.11.10/vue.min.js"></script>
<script>
new Vue({
el: '#container',
data: {
value: '',
},
created: function() {
console.log('Value', a);
}
});
</script>
Example: https://codepen.io/mnbhardwaj888/pen/PooPyjV

Vue js attributes in xpage Vue.js

Attributes not rendered when running xpage:
:Source code:
<div id="categories" class="article-search-results-categories">
<ul class="table-view">
<li class="table-view-cell pr40" v-for="row in list.categories">
<xp:span id="clickSpan">{{row.name }}
<xp:this.attrs>
<xp:attr name="v-on:click" value="alert('ok')" rendered="true"
</xp:attr>
</xp:this.attrs>
</xp:span>
</li>
</ul>
</div>
Script
var app = new Vue ({
el: '#app',
data: {
list:[]
},
methods:{
getUsers: function(){
var link = 'https://jsonplaceholder.typicode.com/users';
this.$http.get(link).then(function(response){
this.list = response.data;
}, function(error){
console.log(error.statusText);
});
},
getCategoryJSON: function(){
var config = {
headers : {
'Content-Type' : 'application/json'
}
}
var data = {
"supplierid": "DAHL"
};
data = JSON.stringify(data);
axios.post
('ProductViewJSONCtrl.xsp',data,config).then(function(response){
app.list = response.data;
}, function(error){
console.log(error.statusText);
});
},
getLevel: function(row){
console.log('clicked');
}
},
mounted : function(){
console.log("in mounted");
this.getCategoryJSON();
}
});
Output:
<span id="view:_id1:_id2:_id295:includeBody:_id328:clickSpan">VA-
armatur/Stängventiler</span>
Any ideas why these attributes can't render?
The example with just the xpage tag is correctly generated but the problem is when the spabn is in the v-for loop
Edited m surrounding codeas the problem is when VUE.js attahces and runs for loop
This
<xp:span
id="clickSpan">
{{row.name }}
<xp:this.attrs>
<xp:attr
name="v-on:click"
value="alert('ok')"
rendered="true" />
</xp:this.attrs>
</xp:span>
renders
<span id="view:_id1:clickSpan" v-on:click="alert('ok')">{{row.name }}</span>
So, it works.
I guess you have a syntax error in source panel and your changes don't take effect yet.

VueJS 2 update contenteditable in component from parent method

I have editable element updated by component method, but i have also json import and i want to update element my parent method. I can update model, but editable element doesn´t bind it. If i insert content to component template, it will bind updated model, but then i can´t really edit it.
Here´s my example: https://jsfiddle.net/kuwf9auc/1/
Vue.component('editable', {
template: '<div contenteditable="true" #input="update"></div>', /* if i insert {{content}} into this div, it wil update, but editing behave weird */
props: ['content'],
mounted: function () {
this.$el.innerText = this.content;
},
methods: {
update: function (event) {
console.log(this.content);
console.log(event.target.innerText);
this.$emit('update', event.target.innerText);
}
}
})
var app = new Vue({
el: '#myapp',
data: {
herobanner: {
headline: 'I can be edited by typing, but not updated with JSON upload.'
}
},
methods: {
uploadJSON: function (event) {
var input = event.target;
input.src = URL.createObjectURL(event.target.files[0]);
var data = input.src;
$.get(data, function(data) {
importdata = $.parseJSON(data);
this.$data.herobanner = importdata.herobanner;
}.bind(this));
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<main id="myapp" class="container-fluid">
<input type="file" id="file" name="file" #change="uploadJSON" style="display: none; width: 1px; height: 1px"/>
<a href="" onclick="document.getElementById('file').click(); return false" title="Import settings from JSON file">
upload JSON
</a>
<h1>
<editable :content="herobanner.headline" #update="herobanner.headline = $event"></editable>
</h1>
Real value of model:
<br>
<h2>{{herobanner.headline}}</h2>
</main>
Working example:
Vue.component('editable', {
template: `
<div contenteditable="true" #blur="emitChange">
{{ content }}
</div>
`,
props: ['content'],
methods: {
emitChange (ev) {
this.$emit('update', ev.target.textContent)
}
}
})
new Vue({
el: '#app',
data: {
herobanner: {
headline: 'Parent is updated on blur event, so click outside this text to update it.'
}
},
methods: {
async loadJson () {
var response = await fetch('https://swapi.co/api/people/1')
var hero = await response.json()
this.herobanner.headline = hero.name
},
updateHeadline (content) {
this.herobanner.headline = content
}
}
})
<main id="app">
<button #click="loadJson">Load JSON data</button>
<h1>
<editable
:content="herobanner.headline"
v-on:update="updateHeadline"
>
</editable>
</h1>
<h2>{{herobanner.headline}}</h2>
</main>
<script src="https://unpkg.com/vue#2.5.3/dist/vue.min.js"></script>