Consuming API not working, what am I doing wrong here? - javascript

Not sure if this is the place to change things, but I have changed some things due to your comments, I stil cant see the pictures, but here is an update of the code:
JS app:
import axios from 'axios';
export default {
name: 'home',
components: {
ImageCard
},
data() {
return {
images: []
}
},
methods: {
fetchImages = () => {
axios
.get("https://foodish-api.herokuapp.com/api/images/pizza")
.then(res => {
console.log(res);
this.setState({ images: res.data.message });
})
.catch(err => console.log(err));
this.images = fetchImages()
});
}
Index.cshtml code here:
<div id="app">
<div class="home">
<li v-for="image in images" :key="image.id">
<img :src="image.url" :alt="image.alt" />
</li>
</div>
Obviously something wrong here but i cant seem to get it right since I cant see the pictures, what is still wrong here? Also, when your refer to something I should do different, please just point me in the right direction of the code :D

you did wrong the following:
create a method fetchImages and never call it.
this.setState this undifined function.
this.images = fetchImages() will lead you to infinite loop because this is a recursion function
in your html use :src="image.url" to show the image but you get the data as string not object and you must use :src="image"
you can check the solution in this codesandbox project
https://codesandbox.io/s/busy-ellis-rcifm?file=/src/App.vue
<template>
<div id="app">
<li v-for="image in images" :key="image.id">
<img :src="image" :alt="image.alt" />
</li>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "App",
data() {
return {
images: [],
};
},
mounted() {
axios
.get("https://foodish-api.herokuapp.com/api/images/pizza")
.then((res) => {
this.images = res.data;
})
.catch((err) => console.log(err));
},
};
</script>

Firstly,when you call fetchImages(),you need to set this.images=fetchImages(),so that the data of images will be set.And if you want to display pictures,you can do like this:
<li v-for="image in images" :key="image.id">
<img :src="image.url" :alt="image.alt"/>
</li>

Related

Astronomy picture of the day Vue application

I am new to vue and I am trying to call the APOD (Astronomy picture of the day) from NASA so that I can display a new picture every day. I am making a new Vue component called Picture.vue where I do all of the accessing of the APOD api. I have been able to get the proper url for the picture I want to display from the response payload (and store in a variable called 'apod') but simply put I don't know how to put the "apod" variable as a 'src' value into either a regular HTML 'img' tag or a vuetify 'v-img' tag. I have a feeling this could be solved with v-bind but like I said I am new to Vue so any tips or guidance would be most appreciated.
Picture.vue
<section class="picture">
<h1>picture Component</h1>
<v-img src="{{apod}}"></v-img>
</section>
</template>
<script lang="js">
const url = "https://api.nasa.gov/planetary/apod?api_key=" + process.env.VUE_APP_KEY;
const axios = require('axios');
export default {
name: 'picture',
props: [],
async created () {
console.log("https://api.nasa.gov/planetary/apod?api_key=" + process.env.VUE_APP_KEY);
// axios.get(url)
// .then(response => this.apod = response.data.url);
const response = await axios.get(url);
this.apod = response.data.url;
console.log(response);
},
data () {
return {
apod: null
}
},
methods: {
},
computed: {
},
state () {
},
}
</script>
<style scoped lang="scss">
.picture {
}
</style>
App.vue
<template>
<v-app>
<Picture></Picture>
</v-app>
</template>
<script>
import Picture from './components/Picture'
export default {
name: 'App',
components: {
Picture,
},
data() {
return {
}
}
};
</script>
In summary my question is how can I put the 'apod' variable as the value of 'src' in an image tag (Vuetify or HTML)?
Thanks very much everyone happy easter!
Use :src and remove the {{ }}
like this
<v-img :src="this.apod" />

VUEJS i want import image file directly in variable

i want import image file from specific link into my vue variable can someone help me
i tried with required but it doesn't work this.imagefile = require(linkofimage)
does anyone know how to solve it
I suggest you to import first the images as constants and assign them to your vue data properties in hooks or methods:
<template>
<div>
<img :src="imageDirect" alt="alert">
<img :src="imageOnHook" alt="alert">
<img :src="imageOnMethod" alt="alert">
<img :src="imageRequire" alt="alert">
</div>
</template>
<script>
const image = require('#/assets/alert_logo_card.png')
export default {
data: () => ({
imageDirect: image,
imageOnHook: null,
imageOnMethod: null,
imageRequire: null,
}),
mounted() {
this.imageOnHook = image
this.imageRequire = require('#/assets/alert_logo_card.png')
this.assignImage()
},
methods: {
assignImage() {
this.imageOnMethod = this.imageDirect
}
}
}
</script>
I'm using the same image just for example purpose.
Something like this also will work:
methods: {
assignImage() {
this.imageOnMethod = this.imageDirect
}
}
Showing an image from the network:
<template>
<div>
<img :src="imageFromUrl" alt="alert" width="200" height="200">
</div>
</template>
<script>
export default {
data: () => ({
imageFromUrl: null
}),
mounted() {
setTimeout(() => {
this.requestImage()
}, 2000);
},
methods: {
requestImage() {
const responseFromNetwork = 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/12/Google_Photos_icon_%282020%29.svg/1024px-Google_Photos_icon_%282020%29.svg.png'
this.imageFromUrl = responseFromNetwork
}
}
}
</script>

Display RSS Feed on front end

I want to display a series of articles from this Google Alert RSS Feed (https://www.google.ie/alerts/feeds/10663948362751557705/4511034072220974544) on my Vue.js application.
I have created a "Feed.vue" component and wish to display the feed on "App.vue". My backend is Express.js. First off, am I even doing this correct? I got this working in Javascript but I want to use Vue.js as my front end.
For some reason I am getting this error regarding my title:
enter image description here
My code:
Feed.vue
<template>
<li>
{{feed.title}}
</li>
</template>
<script>
export default {
props: ["feed"]
}
</script>
App.vue
<template>
<div id="app">
<Feed></Feed>
<ul>
<feed v-for="feed in feeds" :feed="feed" :key="feed.title"></feed>
</ul>
</div>
</template>
<script>
import io from 'socket.io-client'
import Feed from './components/Feed.vue'
export default {
components: {
Feed
},
data () {
return {
feeds: []
}
},
mounted() {
this.subscribeToFeed();
},
methods: {
subscribeToFeed() {
const socket = io();
socket.on('feed', data => {
data.feed.entries().forEach(feed => {
this.feeds.push(feed);
});
});
}
}
}
</script>
Where do I place this in my code?
const socket = io();
socket.on('feed', data => {
for (const [i, item] of data.feed.entries()) {
let itemContainer = $('<span></span>')
.addClass('feed__content')
.append(`<p>${i + 1}) ${item.title}<p>`)
.append(`<p>${item.link}</p>`)
.appendTo('.feed');
}
});
This error happen, because you declared the Feed component without properties in line 3 in App.vue.
Your code is that way:
<template>
<div id="app">
<Feed></Feed> <!-- YOU NEED REMOVE THIS LINE -->
<ul>
<feed v-for="feed in feeds" :feed="feed" :key="feed.title"></feed>
</ul>
</div>
</template>
The correct code is:
<template>
<div id="app">
<ul>
<feed v-for="feed in feeds" :feed="feed" :key="feed.title"></feed>
</ul>
</div>
</template>

How to declare condition statement in nuxt js

I display data using Wordpress API in nuxt js. I try to display data in category wise example where ('post.category ', '=', 'categoryName ') what is the syntax in vuejs/nuxtjs.
Is it even possible?
script:
import axios from 'axios'
export default {
data() {
return {
posts: []
}
},
asyncData() {
return axios.get('http://localhost/wordpress/wp-json/wp/v2/posts')
.then(res => {
return {
posts: res.data
}
})
}
}
template
<div class="col-lg-4" v-for="post in posts" :key="post.id">
<div class="news-post image-post">
<img :src="post.fi_300x180">
<div class="hover-post text-center">
<a class="category-link" href="#">Travel</a>
<h2>{{post.slug}}</h2>
<ul class="post-tags">
<li>by Stan Enemy</li>
<li>3 days ago</li>
</ul>
</div>
</div>
</div>
If i've understood your question right, you're wanting to populate the posts array with the response from your axios get request?
If so, then you could do this as follows:
<template>
<div>
<p v-if="loading">Loading posts...</p>
<div v-for="post in posts" :key="post.id">
<h3>{{ post.title }}</h3>
<p>{{ post.snippet }}</h3>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
posts: [],
loading: false
}
},
created() {
this.fetchData()
}
methods: {
fetchData() {
this.loading = true
axios
.get('endpoint')
.then(res => {
this.posts = res.data.posts
this.loading = false
})
.catch(error => {
//handle error
})
}
}
}
</script>
I've recreated this using a setTimeout function to imitate a call to the api.
https://jsfiddle.net/5b9ofqgh/

Need help limiting array/optimizing axios responses

I have something like /url/{category}.
This is the code to fetch some of these on the main page:
export default {
data() {
return {
topnews:[],
newsfive:[],
categories: {
tshirts:'',
shirts:'',
shoes:'',
useful:'',
}
}
},
methods() {
async getAll(){
axios.all([
axios.get(`/topnews`),
axios.get(`/news`),
axios.get(`/tshirts`),
axios.get(`/shirts`),
axios.get(`/shoes`),
axios.get(`/useful`)])
.then(axios.spread((topnews, news, tshirts, shirts, shoes, useful) => {
news.data.length = 5;
tshirts.data.length = 5
shirts.data.length = 5
shoes.data.length = 5
useful.data.length = 5
// How to limit these appropriately?
this.newsfive = news.data;
this.topnews = topnews.data;
this.categories = {
tshirts: tshirts.data,
shirts: shirts.data,
shoes: shoes.data,
useful: useful.data,
}
})).catch(error => console.log(error))
}
}
created() {
this.getAll()
}
}
This works, but If I change the route to /tshirts and use browser back to the main page, I get:
typeerror content read-only property
Also is it possible to combine this into a single array instead of creating 7 different divs like:
<div v-for="tshirts,key in categories.tshirts" :key="categories.tshirts.slug">
<img :src="tshirts.thumb" class="img-responsive" width=100%/>
<p>{{tshirts.title}}</p>
</div>
Instead have something like a filtered computed axios response and then just use a single div?
<div v-for="item,key in categories(tshirts)" :key="categories(item.slug)">
How can I limit the axios array response size?
Create Category.vue to render only category content
<template>
<div v-for="(item, key) in category" :key="item.slug">
<img :src="item.thumb" class="img-responsive" width=100% />
<p>{{ item.title }}</p>
</div>
</template>
<script>
export default {
data() {
return {
category: { }
}
},
methods() {
getCategory() {
axios.get(`/${this.$route.params.category}`)
.then((response) => {
this.category = response.data.slice(0, 5);
}).catch(error => console.log(error));
}
}
created() {
this.getCategory()
}
}
</script>
And in App.vue add router-link to all categories
<template>
<nav>
<router-link to="{ name: 'category', params: {category: 'tshirts'} }">T-Shirts</router-link>
<router-link to="{ name: 'category', params: {category: 'shirts'} }">Shirts</router-link>
<!-- and other -->
</nav>
<main>
<router-view></router-view>
</main
</template>
Don't forger about vue-router
import Category from "./Category.vue"
routes = [
{
name: "category",
path: "/:categoryId",
component: Category
}
]

Categories

Resources