How should I take a multidimensional array in vuejs? - javascript

This problem has made me sleep well in two days.
This is my code with vuejs & axios & nuxt:
<template>
<ul>
<li v-for="item in data.apilist.interfaces" :key="item" v-if="data.apilist.interfaces">
{{ item.name }}
</li>
</ul>
</template>
<script>
import axios from 'axios'
const util = require('util')
export default {
data: () => ({
title: ''
}),
async asyncData ({ params, error }) {
let res = await axios.get(
`https://bird.ioliu.cn/v1?url=https://api.steampowered.com/ISteamWebAPIUtil/GetSupportedAPIList/v1/`
)
return { data: util.inspect(res, { showHidden: true, depth: null }) }
},
head () {
return {
title: this.title
}
}
}
</script>
Json data : https://api.steampowered.com/ISteamWebAPIUtil/GetSupportedAPIList/v1/
No matter how I do it, I can't get the value of apilist->interfaces->name.
The above example code system prompts me Cannot read property'interfaces' of undefined , which part is the problem?
===================update
I have installed chrome vue dev, but it seems to work on nuxt applications. Now I try to print the entire data data.
The data generated when I typed the corresponding connection directly in the browser is as follows:
enter image description here
But strange things happen, and when I jump to this link from somewhere else in the application, the data data is like this:
enter image description here
I tried v-for="item in data.apilist" {{item.interfaces.name}} or v-if="data.apilist" or v-if="data" and he no longer complains but no data is generated.
This is the result of the powershell output:
enter image description here && enter image description here

Cannot read property'interfaces' of undefined
Simply means that you are trying to access to the property "interfaces" on a undefined reference : somethingThatDoesntExist.interfaces
Here is the mess :
<li v-for="item in data.apilist.interfaces" :key="item" v-if="data.apilist.interfaces">
{{ data.interfaces }}
</li>
You are iterating on data.apilist.interfaces and binding just beneath :
data.interfaces
But you need to bind
item.interfaces
Since you are using v-for="item in ..." and not v-for="data in ...".
Code review is important before asking.

Related

Vuejs How to have many <a> tags and hashtags within <router-link> or #click function

enter image description here
i want to have a post card like twitter post card, if clicked on any part of the post card goes to post page, but when clicked on hashtags or links goes to the hashtag or link
example below
1.
<div #click="gotoPostPage" class="text-weight-light text-justify">
{{ feed.content }}
check google if you need more information then follow #benny(a tag) or follow these hashtags
#google #finda, #checks, now when i click within this post take me to post page
</div>
now this hits the gotoPostPage function even if link or a tag is clicked
using this also
2.
<router-link :to="`/post/${ feed.id }`">
{{ feed.content }}
check google if you need more information then follow #benny(a tag) or follow
these hashtags
#google #finda, #checks, now when i click within this post take me to post page
</router-link>
goes to even when check google is clicked
Please how can i resolve this, your help is highly appreciated,
Thanks
Add #click.stop to your links. E.g:
<a href="https://google.com" #click.stop>check google</a>
This will stop propagation of click events to the parent DOM elements.
Note: #click.stop is shorthand for #click="e => e.stopPropagation()".
Docs here.
Update, based on data shown in comment:
I would avoid storing HTML id database. That's a really bad pattern. You're supposed to detach the data from the UI layer. You have to allow the UI layer to change, based on device and medium. I'd try to store that data as strings holding a hashtag name and, where the name is different than the hastag, as on object, containing both.
Something like this:
const { createApp, reactive, computed, onMounted, toRefs } = Vue;
createApp({
setup() {
const state = reactive({
items: [],
links: computed(() => state.items.map(
item => ({
name: item.name || `#${item}`,
url: item.url || `/hashtag/${item}`
})
))
});
onMounted(async() => {
/* replace this promise with an axios call to server which returns
an array, similar to the one i'm passing here:
(see axios call example below)
*/
const data = await new Promise(resolve => {
setTimeout(() => {
resolve([
'one',
'two',
'three',
'печаль',
'грусть',
{
name: '#mens',
url: '/hashtag/fıstıklıbaklava'
},
'чайная',
'джаз'
]);
});
})
// example axios call:
/*
const data = await axios
.get('http://endpoint-returning-data')
.then(({data}) => data);
*/
state.items = data;
console.log('See difference betwen items (received from server) \r\n\and links (same data, mapped for template):\r\n', {...state}, '\r\nMakes sense?');
})
return {
...toRefs(state),
log: () => console.log('You clicked on app!')
}
}
}).mount('#app')
<script src="https://unpkg.com/vue#3/dist/vue.global.prod.js"></script>
<div id="app">
<div v-for="link in links" :key="link.url" #click="log">
<a :href="link.url"
v-text="link.name"
#click.stop></a>
</div>
</div>
As you can see, it produces the HTML from the data. The template also applies the stopPropagation(), in the v-for.

Vue.js - How to use v-for in JSON array?

I have JSON output from server:
[
{"id":"2","name":"Peter","age":"24"},
{"id":"4","name":"Lucy","age":"18"},
]
and now I want to use it with v-for directive, but it doesn't work for me.
Here is my export default:
data () {
return {
info: {}
}
},
mounted () {
axios
.get('http://localhost:4000/fetch.php/')
.then(response => (this.info = response.data))
},
And now if I want to display output of info, it works well {{ info }}.
But I need to use v-for directive and display only names.
<p v-if="info.name">{{ info.name }}</p>
But it is not working, only what is working is this: {{ info[0].name }}.
You cannot read the name property directly like this: info.name. Since the output is an array of objects rather than a single object.
data () {
return {
info: [], // make this an empty array
}
},
mounted () {
axios
.get('http://localhost:4000/fetch.php/')
.then(response => (this.info = response.data))
},
Then, you can render the info array in your template using v-for directive:
<ul v-if="info.length">
<li v-for="item in info" :key="item.id">{{ item.name }}</li>
</ul>
Read more about List Rendering in Vue.

HTML in Vue.js not updating after axios get request updates object's property

HTML in Vue.js not updating after axios get request. HTML is:
<span #click="tryResponse">
Data_object: {{ data_object }} <br>
Data_object.serial: {{ data_object.serial }} <br>
</span>
data:
data(){
return{
data_object: {},
}
},
method:
methods: {
tryResponse() {
axios.get('http://127.0.0.1:8000/source/groups/15').then((response) => {
this.data_object.serial = response.data});
}
This is all happening in a file called App.vue (if that is important).
If I look in chrome dev tools Vue, I can see the data object does update and populate with the correct information. But it doesn't update in the html on the page.
Edit:
Everything works fine if I do:
this.data_object = response.data
But the problem comes when I do this:
this.data_object.serial = response.data
The property serial is never declared on the vue instance and therefore is not reactive.
You could use Vue.set(this.data_object, "serial", response.data) this registers it with vue so it will add observers to this variable and it will become reactive
or
declare the serial property on the data object
data(){
return{
data_object: {
serial: ""
},
}
},
Here's a link about reactivity in Vue

Filtering items using a condition (vue.js)

This is now solved
The problem
I am trying to make a filter that does this.
Gets 'name' from session storage and matches it with 'name' on product.
I'm storing all 'logged in' user data on 'sessionStorage' for practice.
I'm storing all the 'products' in 'localStorage'
I'm just doing this as a small project to understand and practice vue & js.
Basically if the product has been created by user x, upon login, user x should only be able to see the products he listed and not the rest of the products.
This is what I can do
I can get the user info from sessionStorage and when creating a product, the user 'name' is passed on along with the product details.
I can also retrieve all the products from localStorage.
I don't know how to come up with a filter using vue.js that does this.
Some code sample would really help me understand whats going on.
Additionally, I want to display the results in html.
Thanks in advance.
},
computed: {
filteredProducts() {
this.products.filter(x => x.name === this.loggedUser[0].user);
}
},
});```
[1]: https://i.stack.imgur.com/W7PMf.png
computed: {
filteredProducts() {
return this.products.filter(x => x.name === this.loggedUser[0].text); // text or user, whichever field is for username
},
},
After that show the list in html use v-for.
<p v-if="filteredProducts.length === 0">No products found</p>
<li v-for="(product, key) in filteredProducts" :key="key">Product: {{ product.description }}, Price {{ product.price }} <button #click="deleteProduct(key)">Delete</button></li>
add delete method
methods: {
// ...
deleteProduct(index) {
this.products.splice(index, 1);
},
}
I think this may work from you (given what you have provided above)
computed: {
filteredProducts () {
return this.products.filter(function (item) {
return (item.name === this.loggedUser[0].name)
}
}
}
Basically, we are filtering the products based on the name that is tagged on that list with the loggedUser name.
Hope this helps.

How can I let the list page remember some params?

I have a Vue project, but there is a issue to me,
In my router.js:
{
path: '/home/aftersale_physicalserver_workpanel/:use_flag/:areapartition_homeshowtext',
meta: { keepAlive: true },
icon: 'compose',
name: 'aftersale_physicalserver_workpanel',
title: 'work panel',
component: resolve => {
require(['./views/main_home/home/components/general_admin_staff_panel/physicalserver/physicalserver_workpanel.vue'], resolve);
}
},
there is the code:
...
<template>
<lml-page
ref="lml_page_ref"
v-if=" origin_data && origin_data.count"
:data_count="origin_data.count"
:current.sync="cur_page"
#change_page_for_parent="server_change_page">
</lml-page>
</template>
...
<script>
export default {
props: {
...
cur_page: 1,
},
</script>
you see the cur_page is the page number. I want the URL append the page number.
because when I enter a detail page, when I go back, there will go to page 1 by default.
My purpose
my purpose is let the list_page remember some params. such as the upper page_number, and some search params. but in Vue I don't know how.
When I from a searched params page enter a detail page, when I go back:
<span class="go-left" #click="$router.go(-1)">
<Icon type="chevron-left"></Icon>
<span>Go back</span>
</span>
there will get a list_page without the searched data.
You would need to use either local storage or a central state, what I use is vuex like this:
onPageChange: function (pageNo) {
this.$store.dispatch(this.$mts.some.SOMETHING, pageNo);
},
Then you can call your store wherever you need and get the page number.
Look for the vuex docs on how to setup state management.
Like this:
this.page = this.$store.getters.some.page

Categories

Resources