So I'm pretty new to VueJS and I've been using it to create a gridlike image gallery. I tried to use v-for to display the images by looping through a JSON file with information about each image. I'll include all that. But this is what shows up (screenshot):
so the images don't show up
I've nonuple-checked the links in relation to the file structure. So here's the code of the component that contains the gallery of images (mind you, the href links DO work):
<template>
<div>
<div v-for="data in images" v-bind:key="data">
<h2>{{data.Name}}</h2>
<a :href="'#'+data.Name">
<img :src="'../../../img/products/'+data.Name+'.png'" :alt="data.Name+'.png'" />
</a>
</div>
</div>
</template>
<script>
import Prods from '../../../other/jsons/products.json'
export default {
data() {
return {images: Prods}
}...</script>
Here's the JSON file (it does fetch the data btw, evidently):
[
{
"ImageId": 0,
"Name": "drinks"
},
{
"ImageId": 1,
"Name": "preppedfood"
},
{
"ImageId": 2,
"Name": "coffee"
},
{
"ImageId": 3,
"Name": "snacks"
},
{
"ImageId": 4,
"Name": "nuts"
},
{
"ImageId": 5,
"Name": "bars"
},
{
"ImageId": 6,
"Name": "water"
},
{
"ImageId": 7,
"Name": "fruit"
},
{
"ImageId": 8,
"Name": "cookies"
},
{
"ImageId": 9,
"Name": "cereal"
},
{
"ImageId": 10,
"Name": "healthfood"
},
{
"ImageId": 11,
"Name": "healthdrinks"
},
{
"ImageId": 12,
"Name": "waterdispenser"
},
{
"ImageId": 13,
"Name": "cutlery"
},
{
"ImageId": 14,
"Name": "office"
},
{
"ImageId": 15,
"Name": "more"
}
]
Here's my file structure: enter image description here
put your img folder into /static folder and modify your path
see :
Related
I have products two types: simple and configurable:
"products" : [
{
"type": "simple",
"id": 1,
"sku": "s1",
"title": "Product 1",
"regular_price": {
"currency": "USD",
"value": 27.12
},
"image": "/images/1.png",
"brand": 9
},
{
"type": "configurable",
"id": 2,
"sku": "c1",
"title": "Product 2",
"regular_price": {
"currency": "USD",
"value": 54.21
},
"image": "/images/conf/default.png",
"configurable_options": [
{
"attribute_id": 93,
"attribute_code": "color",
"label": "Color",
"values": [
{
"label": "Red",
"value_index": 931,
"value": "#ff0000"
},
{
"label": "Blue",
"value_index": 932,
"value": "#0000ff"
},
{
"label": "Black",
"value_index": 933,
"value": "#000"
}
]
},
{
"attribute_code": "size",
"attribute_id": 144,
"position": 0,
"id": 2,
"label": "Size",
"values": [
{
"label": "M",
"value_index": 1441,
"value": 1
},
{
"label": "L",
"value_index": 1442,
"value": 2
}
]
}
],
"variants": [
{
"attributes": [
{
"code": "color",
"value_index": 931
},
{
"code": "size",
"value_index": 1441
}
],
"product": {
"id": 2001,
"sku": "c1-red-m",
"image": "/image/conf/red.png"
}
},
{
"attributes": [
{
"code": "color",
"value_index": 931
},
{
"code": "size",
"value_index": 1442
}
],
"product": {
"id": 2002,
"sku": "c1-red-l",
"image": "/image/conf/red.png"
}
},
{
"attributes": [
{
"code": "color",
"value_index": 932
},
{
"code": "size",
"value_index": 1441
}
],
"product": {
"id": 2003,
"sku": "c1-blue-m",
"image": "/image/conf/blue.png"
}
},
{
"attributes": [
{
"code": "color",
"value_index": 933
},
{
"code": "size",
"value_index": 1442
}
],
"product": {
"id": 2004,
"sku": "c1-black-l",
"image": "/image/conf/black.png"
}
}
],
"brand": 1
}
]
The above data I get with actions (Vuex)
GET_PRODUCTS_FROM_API({ commit }) {
return axios('http://localhost:8080/products', {
method: 'GET',
})
.then((products) => {
commit('SET_PRODUCTS_TO_STATE', products.data);
return products;
})
.catch((e) => {
console.log(e);
return e;
});
}
then I mutate the data:
SET_PRODUCTS_TO_STATE: (state, products) => {
state.products = products
}
and get from in getters
PRODUCTS(state) {
return state.products = state.products.map((product) => {
const brand = state.brands.find((b) => b.id === product.brand)
return {...product, brandName: brand?.title || 'no brand'}
})
}
after which i get the data in the component
At the moment I'm stuck on how to render the color and size attributes of a configurable product. Tell me how to do it right? Do I need to write logic in vuex or parent component?
I tried to push data from parent component to child. But it stopped there again.
I also tried to separate the color and size attributes separately using getters.
For Vuex, the syntax is the following
<template>
<div>
<div v-for="product in products" :key="product.id">
<span>type: {{ product.type }}</span>
<span>type: {{ product.title }}</span>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['products']),
...mapGetters('fancyNamespace', ['products']), // if namespaced
},
}
</script>
As of where to call it, directly into the component I guess. Otherwise, as explained here it may not be relevant to use Vuex at all.
PS: you can even rename on the fly if you want.
Solved this issue by Computed Properties and transfer props to child components
computed: {
getAttributeColors() {
let attributes_colors = []
this.product_data.configurable_options.map((item) => {
if(item.label === 'Color') {
attributes_colors.push(item.values)
}
})
return attributes_colors
},
getAttributeSize() {
let attributes_size = []
this.product_data.configurable_options.map((item) => {
if(item.label === 'Size') {
attributes_size.push(item.values)
}
})
return attributes_size
}
}
anyone know about primevue datatable i want to render nested data in primevue components so anyone can help me!
"data": [
{
"id": 71,
"name": "Pearlie Gorczany",
"type": "plot",
"transfer_log": [
{
"id": 3,
"product_id": 71,
"seller_id": 13,
"sellerable_type": "App\\Models\\Agency\\Agency",
"sellerable_id": 1,
"buyer_id": 14,
"buyerable_type": "App\\Models\\Agency\\Agency",
"buyerable_id": 2,
"demand_price": 138393,
"selling_price": 8989,
"created_at": "2022-10-25T05:19:58.000000Z",
"updated_at": "2022-10-25T05:19:58.000000Z",
"buyer": {
"id": 14,
"name": "Cale Fadel"
},
"seller": {
"id": 13,
"name": "Imogene Jones"
}
}
]
},
],
I want to render this type of json format data in primevue datatable component but cannot render
This is my first attempt at creating a react native project (with redux as well) and I have a question relating to passing down info. I have an API that looks like this :
[
{
"id": 1,
"name": "Module 1",
"topics": [
{
"id": 1,
"name": "Iterators and Helpers",
"course_id": 1
},
{
"id": 2,
"name": "Object Oriented Ruby",
"course_id": 1
},
{
"id": 3,
"name": "One to Many Relationships",
"course_id": 1
},
{
"id": 4,
"name": "Many to Many Relationships",
"course_id": 1
},
{
"id": 5,
"name": "Active Record Basics",
"course_id": 1
},
{
"id": 2,
"name": "Module 2",
"topics": [
{
"id": 9,
"name": "Introduction to Sinatra",
"course_id": 2
},
{
"id": 10,
"name": "Sinatra CRUD",
"course_id": 2
},
{
"id": 11,
"name": "Sinatra Associations",
"course_id": 2
},
{
"id": 12,
"name": "Introduction to Rails",
"course_id": 2
},
{
"id": 13,
"name": "Rails Forms + CRUD",
"course_id": 2
},
{
"id": 14,
"name": "Rails Associations + CRUD",
"course_id": 2
},
{
"id": 15,
"name": "Rails Sessions and Cookies",
"course_id": 2
},
{
"id": 16,
"name": "Rails Authentication and Authorization",
"course_id": 2
},
{
"id": 17,
"name": "Module 2 Project Guidelines",
"course_id": 2
}
]
{
"id": 3,
"name": "Module 3",
"topics": [
{
"id": 18,
"name": "Introduction to JavaScript",
"course_id": 3
},
{
"id": 19,
"name": "Introduction to Document Object Model",
"course_id": 3
},
{
"id": 20,
"name": "JavaScript Events",
"course_id": 3
},
{
"id": 21,
"name": "JavaScript Asynchronous Functionality + Fetch & CRUD",
"course_id": 3
Each 'module' has many topics. I want the Modules to appear on one screen and the topics for each course to appear once a button is clicked. I have this so far:
render(){
console.log(this.props.courseNames)
return(
<FlatList style={styles.flatlist} keyExtractor={(item)=> item.id} data={this.props.courseNames} ItemSeparatorComponent = { this.FlatListItemSeparator }
renderItem={({item}) => {
return <TouchableOpacity><Button title={item.name} onPress={() => this.props.navigation.navigate('Topics')} style={styles.listitem}/></TouchableOpacity>
}}
ListHeaderComponent = {this.header}/>
)
}
}
This is just a snippet but I'm wondering how I can pass down the information specific to that class so that I can retrieve all the topics that it contains and display them on the next screen. Any pointers would be great! thanks!
I think you're asking how to pass 'parameters' to navigation routes, which, yes, do render components that can receive props from the navigation route parameter.
In your case,
this.props.navigation.navigate('Topics')
should be changed to;
this.props.navigation.navigate('Topics', {id:item.id})
Once you navigate to your Topics route, that component will be able to read the 'id' value from;
props.route.params.id
Route parameters will be any object passed after the route name in this.props.navigation.navigate method.
This is driving me crazy, I have nested data in an array and have not been successful in getting it to render using components, I am able to render it without a component though.
var data2 = {
"team": [{
"id":0,
"author": "Johnnie Walker",
"title": "Aging Your Own Whisky",
"content": "A bunch of steps and a whole lot of content",
"members": [
{
"id": "0",
"name": "name 1",
"text": "bio"
},
{
"id": "1",
"name": "name 2",
"text": "bio"
}
]
},
{
"id":1,
"author": "Captain Morgan",
"title": "Rum stories",
"content": "A bunch of steps and a whole lot of contentttt",
"members": [
{
"id": "3",
"name": "name 3",
"text": "bio"
}
]
}
]}
What I am trying to do is loop through members, here is my current code
index.html
<div id="app2">
<entry v-for="t in team" v-bind:cat="t" v-bind:key="t.id">
<detail v-for="mem in t.members" v-bind:ember="mem" v-bind:key="mem.id"></detail>
</entry>
</div>
and here is my js file
Vue.component('entry', {
props:['cat'],
template: '<div>{{cat.author}}</div>'
})
Vue.component('detail', {
props:['ember'],
template: '<div>{{ember.id}}</div>',
})
var vm2 = new Vue({
el: '#app2',
data: function() {
console.log(data2.team)
return data2;
}
});
The data in entry renders but nothing happens with detail, no warnings either, how do I proceed?
Note: When I approach it this way it DOES work, but this is not using a component:
var vm = new Vue({
el: '#app',
data: function() {
console.log(data2.team)
return data2;
}
});
and the html
<div id="app">
<div v-for="t in team" v-bind:key="t.id" v-bind:author="t.author">
{{t.author}}
<div v-for="m in t.members" v-bind:key="m.id">
{{m.name}}
</div>
</div>
</div>
You either need to add the detail component to the entry template, or you need to add a slot to the entry component.
Here is your code modified to use a slot.
console.clear()
var data2 = {
"team": [{
"id": 0,
"author": "Johnnie Walker",
"title": "Aging Your Own Whisky",
"content": "A bunch of steps and a whole lot of content",
"members": [{
"id": "0",
"name": "name 1",
"text": "bio"
},
{
"id": "1",
"name": "name 2",
"text": "bio"
}
]
},
{
"id": 1,
"author": "Captain Morgan",
"title": "Rum stories",
"content": "A bunch of steps and a whole lot of contentttt",
"members": [{
"id": "3",
"name": "name 3",
"text": "bio"
}]
}
]
}
Vue.component('entry', {
props: ['cat'],
template: '<div>{{cat.author}}<slot/></div>'
})
Vue.component('detail', {
props: ['ember'],
template: '<div>{{ember.id}}</div>',
})
var vm2 = new Vue({
el: '#app2',
data: function() {
console.log(data2.team)
return data2;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app2">
<entry v-for="t in team" v-bind:cat="t" v-bind:key="t.id">
<detail v-for="mem in t.members" v-bind:ember="mem" v-bind:key="mem.id">
</detail>
</entry>
</div>
And here it is modifying the entry component to include the detail.
console.clear()
var data2 = {
"team": [{
"id": 0,
"author": "Johnnie Walker",
"title": "Aging Your Own Whisky",
"content": "A bunch of steps and a whole lot of content",
"members": [{
"id": "0",
"name": "name 1",
"text": "bio"
},
{
"id": "1",
"name": "name 2",
"text": "bio"
}
]
},
{
"id": 1,
"author": "Captain Morgan",
"title": "Rum stories",
"content": "A bunch of steps and a whole lot of contentttt",
"members": [{
"id": "3",
"name": "name 3",
"text": "bio"
}]
}
]
}
Vue.component('detail', {
props: ['ember'],
template: '<div>{{ember.id}}</div>',
})
Vue.component('entry', {
props: ['cat'],
template: `<div>
{{cat.author}}
<detail v-for="mem in cat.members" v-bind:ember="mem" v-bind:key="mem.id">
</detail>
</div>`
})
var vm2 = new Vue({
el: '#app2',
data: function() {
return data2;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app2">
<entry v-for="t in team" v-bind:cat="t" v-bind:key="t.id"></entry>
</div>
"data": {
"offset": 0,
"limit": 20,
"total": 1,
"count": 1,
"results": [
{
"id": 1009144,
"name": "A.I.M.",
"modified": "2013-10-17T14:41:30-0400",
"thumbnail": {
"path": "i.annihil.us/u/prod/marvel/i/mg/6/20/52602f21f29ec",
"extension": "jpg"
},
"resourceURI": "gateway.marvel.com/v1/public/characters/1009144",
"comics": {
"available": 33,
"collectionURI": "gateway.marvel.com/v1/public/characters/1009144/comics",
"items": [
{
"resourceURI": "gateway.marvel.com/v1/public/comics/36763",
"name": "Ant-Man & the Wasp (2010) #3"
},
{
"resourceURI": "gateway.marvel.com/v1/public/comics/17553",
"name": "Avengers (1998) #67"
}
]
}
}
]
}
I am using axios to fetch datas from an api inside a React component. I would like to access to the key items in my json response in order to setState but I can't.
export default class Hero extends React.Component {
constructor(props) {
super(props);
this.state = {
details : [],
comics :[]
};
}
componentDidMount() {
axios.get(infoUrl).then((res) => {
this.setState({details : res.data.data.results,
comics : res.data.data.results.results[6].items});
})
}
render() {
(<div>
</div>)
}
}
I can access to my state details but not the comics one.
items being present in comics is not the 6th item in the result array but the 6th item in the first object of the result array and hence you need to access it like.
res.data.data.results[0].comics.items
Change you componentDidMount function to
componentDidMount() {
axios.get(infoUrl).then((res) => {
this.setState({details : res.data.data.results,
comics : res.data.data.results[0].items});
})
}
Results array contains only one item, so you need to use index 0 instead of 6. Another thing is items is present inside comics, so first access comics then access items, use this:
componentDidMount() {
axios.get(infoUrl).then((res) => {
this.setState({
details : res.data.data.results,
comics : res.data.data.results[0].comics.items});
})
}
Run this snippet:
let data = {"data": {
"offset": 0,
"limit": 20,
"total": 1,
"count": 1,
"results": [
{
"id": 1009144,
"name": "A.I.M.",
"modified": "2013-10-17T14:41:30-0400",
"thumbnail": {
"path": "i.annihil.us/u/prod/marvel/i/mg/6/20/52602f21f29ec",
"extension": "jpg"
},
"resourceURI": "gateway.marvel.com/v1/public/characters/1009144",
"comics": {
"available": 33,
"collectionURI": "gateway.marvel.com/v1/public/characters/1009144/comics",
"items": [
{
"resourceURI": "gateway.marvel.com/v1/public/comics/36763",
"name": "Ant-Man & the Wasp (2010) #3"
},
{
"resourceURI": "gateway.marvel.com/v1/public/comics/17553",
"name": "Avengers (1998) #67"
}
]
}
}
]
}
}
console.log('items', data.data.results[0].comics.items)