Use an img with vue and axios - javascript

I'm using vue and I try to use img but every time I make the request it doesn't show anything this how I got the code.
app.js:
const vm = new Vue({
el: '#app',
data: {
results: []
},
mounted() {
axios.get("xxxxxxxxxx")
.then(response => {
this.results = response.data
})
}
});
html:
<div class="container" id="app">
<h3 class="text-center">VueNews</h3>
<div class="columns medium-3" v-for="result in results">
<div class="card">
<div class="card-divider">
{{ result.titulo_periodico }}
</div>
<div class="card-section">
<img src="{{ result.photos[0].urls[2].original }}" alt="">
<p>{{ result.photos[0].urls[2].original }}</p>
</div>
</div>
</div>
</div>
The main information it work like the title and even display the url but when I try to use it with img src="" it doesn't do anything
I will really appreciate if you can help me it this issue.

The src attribute needs to be set as a bound attribute.
<img v-bind:src="result.photos[0].urls[2].original" alt="">

Related

Vuejs v-bind v-for not populating into component template

with html
<div id="app">
<gallery v-bind:links="['link1.jpg', 'link2.jpg']" />
</div>
and component definition:
Vue.component('gallery', {
template: `
<div v-if="!isReady">
not ready
</div>
<div v-else>
<image-grp v-for="src in links">
<img v-bind:src="src">
</image-grp>
</div>
`,
data() {
return {
links: [],
isReady: false
}
},
mounted() {
this.links = this.$el.getAttribute('links').split(',')
this.isReady = true
console.log(this.links);
}
});
I've managed to produce this html:
<div links="link1.jpg,link2.jpg">
<div class="image">
<img src="">
</div>
<div class="image">
<img src="">
</div>
</div>
The images are not showing up because of the empty src. The src should be filled in during the loop on src in links. The array links must be filled properly, cause the html shows the same number of image-grp elements as are in the links array.
I have tried a variety of ways to populate/bind/mustache the src into the dynamic <img src=""> elements. Any guidance would be appreciated.
I don't see any problems with your code. It works.
But you should better make links to props, like this:
props: ['links']
Then, the other commented out lines are not needed.
Playground
Vue.component('gallery', {
props: ['links'],
template: `
<div v-if="!isReady">
not ready
</div>
<div v-else>
<image-grp v-for="src in links">
<img v-bind:src="src">
</image-grp>
</div>
`,
data() {
return {
//links: [],
isReady: false
}
},
mounted() {
//this.links = this.$el.getAttribute('links').split(',');
this.isReady = true;
}
});
const app = new Vue({
el: '#app'
})
img {
width: 100px;
height: 100px;
margin: 4px;
}
<div id="app">
<gallery v-bind:links="['https://i.stack.imgur.com/NxnaT.jpg?s=256&g=1', 'https://www.gravatar.com/avatar/50309120892edf29dcb2188bdabe3b08?s=256&d=identicon&r=PG']"></gallery>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#^2.0.0/dist/vue.min.js"></script>

how to rendering data from api in vue.js

I am new to vue.js I am going to make a news app using a API.
In here I used v-for to iterate some codes. I think there is a problem in v-for. because it gives error. error has been included end of this question.
I used following codes to show search results
<template>
<div class="col-md-12">
<div>
<h2>Results</h2>
<div class="card mb-3" v-for="item in resultList">
<img class="card-img-top" src="" alt="Card image cap" height="100" width="200">
<div class="card-body">
<h5 class="card-title">{{ item.name }}</h5>
<p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
<div class="button">
<button type="button" class="btn btn-primary">Show more</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default{
props: ['resultList']
}
</script>
following codes used to get the api data(search api data)
<template>
<div class="container1">
<div class="form-group row">
<label for="exampleInputPassword1">Search Music</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="exampleInputPassword1" placeholder="Type here"
#input="keypressed">
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default{
data () {
return {
newset: []
}
},
methods: {
keypressed () {
var key = event.target.value
axios.get('http://newsapi.org/v2/everything?q=' + key +
'&sortBy=publishedAt&apiKey=b5ac77726d0a4460bd82b57210b2efb7')
.then(response => {
this.newset = response.data.articles
})
.catch(e => {
this.error.push(e)
})
this.$emit('newDataset', this.newset)
}
}
}
</script>
but it gives an error. error is
https://google.com/#q=vue%2Frequire-v-for-key Elements in iteration expect to have 'v-
bind:key'
directives
src\components\ResultArea.vue:5:5
<div class="card mb-3" v-for="item in resultList">
^
You need to add :key binding:
<div class="card mb-3" v-for="(item, index) in resultList" :key="index">
key value should be unique for every item. If your list items has any id it is good idea to use this id here:
<div class="card mb-3" v-for="item in resultList" :key="item.id">
To give Vue a hint so that it can track each node’s identity, and thus reuse and reorder existing elements, you need to provide a unique key attribute for each item. check the link for better understanding
https://v2.vuejs.org/v2/guide/list.html#Maintaining-State

How to add additional url in Vue JS

Hi I am using django and Vue to make an webapp. I am rendering data using v-for and fetching the data from a restful API using XMLHttprequest
This is my custom js file. I am not using Vue CLI I am using a CDN:
$(document).ready(function () {
function fetchData(){
Vue.component('postcontainer', {
props:['obj'],
template:
`<div>
<div v-for="data in obj" class="ui mt-3 card">
<div class="content">
<div class="right floated meta">{{data.date_posted}}</div>
<img class="ui avatar image" src="https://cdn.pixabay.com/photo/2017/08/30/12/45/girl-2696947_960_720.jpg">
{{data.author}}
</div>
<div v-if="data.image" class="image">
<img v-bind:src="[[data.image]]">
</div>
<div v-if="data.video">
<video controls v-bind:src="[[data.video]]" class="embed-responsive"></video>
</div>
<div class="content">
<div v-if="data.title">
<a class="text-dark" :href="data.id"><h3 class="header">{{data.title}}</h3></a>
</div>
<div class="description my-2">
<div v-if="data.caption">
<a class="text-dark" :href="data.id"><p>{{data.caption}}</p></a>
</div>
</div>
</div>
<div class="extra content">
<span class="right floated">
<i class="heart outline like icon"></i>
17 likes
</span>
<a :href="data.id"><i class="comment icon"></i></a>
</div>
</div>
</div>
`
})
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var app = new Vue({
el: '#postCard',
component:['postconatiner'],
data: {
obj: JSON.parse(this.responseText),
}
})
}
}
xhr.open('GET', '/data/', true);
xhr.LOADING
xhr.send()
}
fetchData()
});
I want add an additional url before data.id example - ":href = 'detail/data.id'". My problem is when I try to add this the url becomes 'localhost:8000/NaN'. Please some help me. Also I want to if it's the right way to render html using VueJS.
Use the binded property href like this:
:href="'details/'+data.id"

Displaying information using v-if from an API

I want the tag that currently says true or false, I want it to say "FREE" if it's free and say "PAID" if it's not.
https://www.eventbriteapi.com/v3/events/search/?location.address=45+Depot+Ave.++Bronx%2C+NY+10457&location.within=50mi&token=6RXWSSZPE4APEYSWTJJF
I'm getting a response from data.events.is_free in the form of a boolean that's true if free and false if not.
I know I have nothing between the v-if tags, but the whole thing goes blank if add anything.
HTML:
<div id="app" class="container">
<h1 id="header" class="title is-1 has-text-centered">Event Lookup for ECH</h1>
<div v-for="event in info">
<h2 class="title is-4" id="eventName">{{ event.name.html }} <span v-if="" class="tag is-success">{{ event.is_free }}</span></h2>
<div id="eventDescription">{{ event.description.text }}</div>
<div id="eventDateTime">{{ event.start.local }} - {{ event.end.local }}</div>
</div>
</div>
Vue / JS
// The plan is to make this more extensive later
// https://www.eventbriteapi.com/v3/events/search/?location.address=45+Depot+Ave.++Bronx%2C+NY+10457&location.within=50mi&token=6RXWSSZPE4APEYSWTJJF
// This is a random address...
const baseUrl = 'https://www.eventbriteapi.com/v3/events/search/?location.address=45+Depot+Ave.++Bronx%2C+NY+10457&location.within=50mi&token=6RXWSSZPE4APEYSWTJJF';
new Vue({
el: '#app',
data () {
return {
info: null
}
},
mounted () {
axios
.get(baseUrl)
.then(response => (this.info = response.data.events))
},
computed () {
isFree
if (response.data.events.is_free == true) {
return true;
}
else {
return false;
}
}
})
https://codepen.io/Mortiferr/pen/qyajJd
Here's a link to my Codepen.
You can use v-if and v-else.
<div id="app" class="container">
<h1 id="header" class="title is-1 has-text-centered">Event Lookup for ECH</h1>
<div v-for="event in info">
<h2 class="title is-4" id="eventName">{{ event.name.html }}
<span v-if="event.is_free" class="tag is-success">Free</span>
<span v-else class="tag is-success">Paid</span>
</h2>
<div id="eventDescription">{{ event.description.text }}</div>
<div id="eventDateTime">{{ event.start.local }} - {{ event.end.local }}</div>
</div>
</div>
You don't need a computed property for this. You can use v-if and v-else.
Alternatively, if you know that you will only have the text "FREE" or "PAID" without any markup needed, you might want to consider just using a ternary expression:
<span class="tag is-success">{{event.is_free ? "FREE" : "PAID"}}</span>
I added a cost class just to make it a little easier to see.
const baseUrl = 'https://www.eventbriteapi.com/v3/events/search/?location.address=45+Depot+Ave.++Bronx%2C+NY+10457&location.within=50mi&token=6RXWSSZPE4APEYSWTJJF';
new Vue({
el: '#app',
data() {
return {
info: null,
isFree: false
}
},
mounted() {
axios
.get(baseUrl)
.then(response => {
this.info = response.data.events;
this.isFree = response.data.events
})
}
})
.cost {
color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<div id="app" class="container">
<h1 id="header" class="title is-1 has-text-centered">Event Lookup for ECH</h1>
<div v-for="event in info">
<!-- Using v-if/else -->
<h2 class="title is-4" id="eventName">{{ event.name.html }}
<span v-if="event.is_free" class="cost tag is-success">FREE</span>
<span v-else class="cost tag is-success">PAID</span>
</h2>
<!-- Using ternary -->
<h2 class="title is-4" id="eventName">{{ event.name.html }}
<span class="cost tag is-success">{{event.is_free ? "FREE" : "PAID"}}</span>
</h2>
<!--<div id="eventDescription">{{ event.description.text }}</div>-->
<div id="eventDateTime">{{ event.start.local }} - {{ event.end.local }}</div>
</div>
</div>

Vue.js 2 Route Not Working. Posts Variable not Accessible

First project in Vue.js. Working with WP REST API.
I am able to get all my posts to show, but as soon as I try to implement the Vue-router my component that shows all the posts, home-post-list, dies at the first v-if="posts" statement.
Clearly, Vue thinks there is no posts so it isn't rendering anything else, but I cannot figure out how to make it recognize posts. I don't get any errors in the console.
WhenI look at the Vue DevTools, I see:
https://www.dropbox.com/s/5441k1kw8ocmzad/Screenshot%202018-05-22%2010.43.24.png?dl=0
So, the router-view appears to be working properly, but props is empty. I thought I was passing props from the main instance to the child component but maybe I am doing something wrong here.
I will show you my current code.
***HomePostList component
const HomePostList = Vue.component('home-post-list', {
props:['posts'],
template: `<div class="cell medium-8">
<div id="all-posts" class="all-posts" v-if="posts">
<div class="grid-x grid-margin-x">
<div class="post medium-6 cell" :class="{'medium-12':index===0}" v-for="(post,index) in posts">
<div class="img-bg" :class="{'first-post':index === 0}" :style="'background-image: url(' + post._embedded['wp:featuredmedia']['0'].source_url + ')'"></div>
<aside class="post-meta grid-x">
<div class="cell small-12">
<h3>{{ post.title.rendered | limitWords(6) }}</h3>
</div>
<div class="cell small-6">
<div class="post-category" v-for="(category,index) in post.cat_name.slice(0,1)">
<a :href="'/category/' + category.slug">{{ category.cat_name }}</a>
</div>
</div>
<div class="cell small-6">
<p><i class="fal fa-calendar-alt"></i> {{ post.date | parseTime }}</p>
</div>
</aside>
</div>
</div>
</div>
</div>`
});
***SinglePost Component
const SinglePost = Vue.component('single-post-template', {
props:['posts'],
template: `<div class="cell medium-8">
<div class="grid-x grid-margin-x">
<p>Single Post here</p>
</div>
</div>`
});
***Routes & Vue Instance
const routes = [
{
path: '/',
component: HomePostList,
props: true
},
{
path: '/post/:postId',
name: 'post',
component: SinglePost
}
];
const router = new VueRouter({
routes
});
new Vue({
el: '#app',
router,
data() {
return{
posts: [],
searchTerm:'',
searchPosts:[],
currentRoute: window.location.pathname
}
},
created (){
var $this = this;
axios
.get(apiRoot + 'posts?_embed')
.then(function (response) {
$this.posts = response.data;
}
)
},
methods: {
loadMorePosts: function(){
var $this = this;
axios
.get(apiRoot + 'posts?_embed')
.then(function (response) {
$this.posts = response.data;
}
)
},
},
computed:{
},
});
***index.php
<?php
/*
Template Name: Front
*/
get_header(); ?>
<!-- Home Page -->
<div class="grid-container">
<div class="grid-x grid-margin-x">
<!-- Main Post Container -->
<router-view></router-view>
<!-- Sidebar -->
<div id="sidebar" class="cell medium-4">
<sidebar-search></sidebar-search>
</div>
</div>
</div>
<?php get_footer();
I got this working by adding posts to the router-view element.
<router-view :posts="posts"></router-view>
Not sure if this is the correct way to do this, but it works.

Categories