Vue select with deep nested data - vue.js

I'm trying to make a v-select according to instruction on official documentation but my data is more nested than it shown in documentation, i can not show in my v-select the llcName of my data, and i'm stuck with this.
This is my html div and Vue instance with data below
<div id="vs">
<h1>Vue Select</h1>
<v-select multiple :options="options" :reduce="node=> node.llcName" label='llcName' v-model='selected' />
<pre>[[$data]]</pre>
</div>
<script>
Vue.component('v-select', VueSelect.VueSelect)
new Vue({
el: '#vs',
delimiters: ["[[", "]]"],
data: {
options: [
{
"node": {
"id": "U3VwcGxpZXJPYmplY3Q6MzA1",
"llcName": "new",
"suppPayment": {
"edges": [0]
}
}
},
{
"node": {
"id": "U3VwcGxpZXJPYmplY3Q6MzA2",
"llcName": "new2",
"suppPayment": {
"edges": [1]
}
}
},
{
"node": {
"id": "U3VwcGxpZXJPYmplY3Q6MzA3",
"llcName": "rteer",
"suppPayment": {
"edges": [2]
}
}
}
],
selected:"",
}
})
</script>

I think you should use getOptionLabel instead of label and there is a mistake in your reduce property.
<v-select
multiple
v-model='selected'
:options='options'
:get-option-label='option => option.node.llcName'
:reduce='option => option.node.llcName'/>
Fiddle

Related

how do i modify, then filter my object property in vuejs

I have an object that comes into my model. I want break the properties up into different sections into the model- so that i can split up the content. I never worked with an object before in this context, but arrays so not sure what is the best way to approach this. So i just want to strip the returned data to just display "ab1e0yeeieieiddk", BUT inside of the model in its designated area.
new Vue({
el: "#app",
data: {
ticket:{"token_type":"Bearer","expires_in":"86399","not_before":"1649632168","expires_on":"1649718868","resource":"00000003-0000-0ff1-ce00-000000000000/contesto.sharepoint.com#ab1e0yeeieieiddk","access_token":"eydsdsadasddefdfdfjfkjnfkflklffjdslnkdsfdisfnlkfmdsjfkfmkdsfjnfjdsfn"},
bearer:"",//taken from all the characters after the #//should be ab1e0yeeieieiddk
access:""//taken from access token. Should be eydsdsadasddefdfdfjfkjnfkflklffjdslnkdsfdisfnlkfmdsjfkfmkdsfjnfjdsfn
},
methods: {
toggle: function(todo){
todo.done = !todo.done
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Ticket Status:</h2>
<p v-if="ticket.resource">{{ticket.resource}}
</p>
{{bearer}}<p v-if="ticket.access_token">{{ticket.access_token}}
</p><br>
{{access}}
</div>
You can split the text simply in the template section like this:
<p v-if="ticket.resource">{{ticket.resource.split('#')[1]}}</p>
new Vue({
el: "#app",
data: {
ticket: {
"token_type": "Bearer",
"expires_in": "86399",
"not_before": "1649632168",
"expires_on": "1649718868",
"resource": "00000003-0000-0ff1-ce00-000000000000/contesto.sharepoint.com#ab1e0yeeieieiddk",
"access_token": "eydsdsadasddefdfdfjfkjnfkflklffjdslnkdsfdisfnlkfmdsjfkfmkdsfjnfjdsfn"
},
bearer: "", //taken from all the characters after the #//should be ab1e0yeeieieiddk
access: "" //taken from access token. Should be eydsdsadasddefdfdfjfkjnfkflklffjdslnkdsfdisfnlkfmdsjfkfmkdsfjnfjdsfn
},
methods: {
toggle: function(todo) {
todo.done = !todo.done
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Ticket Status:</h2>
<p v-if="ticket.resource">{{ticket.resource.split('#')[1]}}</p>
{{bearer}}
<p v-if="ticket.access_token">{{ticket.access_token}}
</p><br> {{access}}
</div>
Or you can create a computed property and convert your data to anything you want and use it in the template:
<p v-if="ticket.resource">{{resourceToShow}}</p>
computed: {
resourceToShow() {
return this.ticket.resource.split('#')[1];
},
},
new Vue({
el: "#app",
data: {
ticket: {
"token_type": "Bearer",
"expires_in": "86399",
"not_before": "1649632168",
"expires_on": "1649718868",
"resource": "00000003-0000-0ff1-ce00-000000000000/contesto.sharepoint.com#ab1e0yeeieieiddk",
"access_token": "eydsdsadasddefdfdfjfkjnfkflklffjdslnkdsfdisfnlkfmdsjfkfmkdsfjnfjdsfn"
},
bearer: "", //taken from all the characters after the #//should be ab1e0yeeieieiddk
access: "" //taken from access token. Should be eydsdsadasddefdfdfjfkjnfkflklffjdslnkdsfdisfnlkfmdsjfkfmkdsfjnfjdsfn
},
computed: {
resourceToShow() {
return this.ticket.resource.split('#')[1];
},
},
methods: {
toggle: function(todo) {
todo.done = !todo.done
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Ticket Status:</h2>
<p v-if="ticket.resource">{{resourceToShow}}</p>
{{bearer}}
<p v-if="ticket.access_token">{{ticket.access_token}}
</p><br> {{access}}
</div>

v-for different object properties and accessing array of objects inside it

In my application I am receiving object as below :
{
"data1":[
{},{}{}
],
"data2":[ {},{},{}....],
"data3":[ {},{},{}.....]
}
If someone can help me on how to use v-for here? I want to loop through "data1", "data2"... using v-for. ( in sinlge v-for precisely )
UPDATE:I would like to have object like this.
data :[{
title :"data1",
values: [{ } {} {}]
},
{
title :"data1",
values: [{ } {} {}]
},
.....
]
You can do something like this :
<div id="app">
<h2>Todos:</h2>
<div v-for="t1 in todos.todos1">
<label>{{t1.text}}</label>
</div>
<div v-for="t2 in todos.todos2">
<label>{{t2.text}}</label>
</div>
<div v-for="t3 in todos.todos3">
<label>{{t3.text}}</label>
</div>
</div>
new Vue({
el: "#app",
data: {
todo:{},
todos:{todos1: [
{ text: "Learn JavaScript 1", done: false },
{ text: "Learn Vue 1", done: false }
],
todos2: [
{ text: "Play around in JSFiddle 2", done: true },
{ text: "Build something awesome 2", done: true }
],
todos3: [
{ text: "Learn Vue 3", done: false },
{ text: "Play around in JSFiddle 3", done: true },
]
}
},
created(){
this.todo = Object.values(this.todos)
console.log(this.todo)
}
})
You can do something like
<div v-for="(value, propertyName, index) in items"></div>
WARNING
When iterating over an object, the order is based on the enumeration order of Object.keys(), which is not guaranteed to be consistent across JavaScript engine implementations.
The above can be found on the Vue Documentation.

How get the data from an array like this with axiosjs

I connected to a URL using Axios using this:
getUsers: function() {
axios.get(urlUsers).then(response => {
this.lists = response.data
});
and get this data:
"lists": [
{
"name": "Destacados",
"tags": [
"Aguila"
],
"isRoot": true,
"products": [
{
"name": "Coors",
"code": "139017",
And tryng to list products.
How?
You can use v-for to render lists. In your case you have a nested array so you would need to do it twice. However I think you should change your data element 'lists' and remove all the excess quotes ("") so it looks like this:
lists: [
{
name: "Destacados",
tags: [
"Aguila",
],
isRoot: true,
products: [
{
name: "Coors",
code: 139017,
},
{
name: "Bud",
code: 139019,
}
],
}
]
and then run your v-for loops:
<template>
<div v-for="list in lists" :key="list.name">
<ul v-for="product in list.products :key="product.name">
<li>{{product.name}}</li>
<li>{{product.code}}</li>
</ul>
</div>
</template>

Vuejs component doesn't update when changing variable

I'm learning Vue.js and have been able to write a simple list/detail application. Selecting the first item renders the detail component with the correct data, however when I select a different item the detail component doesn't reload with the right information.
For example:
<template>
<div>
<detail :obj="currentObject"></detail>
</div>
</template>
<script>
export default: {
data: function(){
return {
currentObject: null,
objs = [
{name:'obj 1'},
{name:'obj 2'}
]
};
}
}
</script>
When I do this.currentObject = objs[0] the component detail updates with the correct content. However the next time I call this.currentObject = objs[1], the component detail no longer updates.
Not sure what's the context your are switching the data on your currentObject, but the below is a concept detail component and when you switch the objs it updated the prop :obj and seems working fine.
Looking at your code, you should declare objs using : not =.
data: function() {
return {
currentObject: null,
objs: [
{name:'obj 1'},
{name:'obj 2'}
]
};
}
Here is the concept detail component, run the snippet to check it working.
Vue.component('detail', {
props: ['obj'],
template: '<div>{{ obj }}</div>'
})
var app = new Vue({
el: '#app',
data() {
return {
bToggle: false,
currentObject: null,
objs: [
{name:'obj 1'},
{name:'obj 2'}
]
}
},
created(){
this.switchData();
},
methods: {
switchData() {
if(!this.bToggle){
this.currentObject = this.objs[0];
}else{
this.currentObject = this.objs[1];
}
this.bToggle = !this.bToggle;
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.17/dist/vue.js"></script>
<div id="app">
<button #click="switchData()"> switch </button>
<detail :obj="currentObject"></detail>
</div>

Passing data into a Vue template

I am fairly new to vue and can't figure out how to add data values within a template. I am trying to build a very basic form builder. If I click on a button it should add another array of data into a components variable. This is working. The I am doing a v-for to add input fields where some of the attributes are apart of the array for that component. I get it so it will add the input but no values are being passed into the input.
I have created a jsfiddle with where I am stuck at. https://jsfiddle.net/a9koj9gv/2/
<div id="app">
<button #click="add_text_input">New Text Input Field</button>
<my-component v-for="comp in components"></my-component>
<pre>{{ $data | json }}</pre>
</div>
new Vue({
el: "#app",
data: function() {
return {
components: [{
name: "first_name",
showname: "First Name",
type: "text",
required: "false",
fee: "0"
}]
}
},
components: {
'my-component': {
template: '<div>{{ showname }}: <input v-bind:name="name" v-bind:type="type"></div>',
props: ['showname', 'type', 'name']
}
},
methods: {
add_text_input: function() {
var array = {
name: "last_name",
showname: "Last Name",
type: "text",
required: "false",
fee: "0"
};
this.components.push(array);
}
}
})
I appreciate any help as I know I am just missing something obvious.
Thanks
Use props to pass data into the component.
Currently you have <my-component v-for="comp in components"></my-component>, which doesn't bind any props to the component.
Instead, do:
<my-component :showname="comp.showname"
:type="comp.type"
:name="comp.name"
v-for="comp in components"
></my-component>
Here is a fork of your fiddle with the change.
while asemahle got it right, here is a boiled down version on how to expose data to the child component. SFC:
async created() {
await this.setTemplate();
},
methods: {
async setTemplate() {
// const templateString = await axios.get..
this.t = {
template: templateString,
props: ['foo'],
}
},
},
data() {
return {
foo: 'bar',
t: null
}
}
};
</script>
<template>
<component :is="t" :foo="foo"></component>
It pulls a template string that is compiled/transpiled into a js-render-function. In this case with Vite with esm to have a client-side compiler available:
resolve: {
alias: {
// https://github.com/vuejs/core/tree/main/packages/vue#with-a-bundler
vue: "vue/dist/vue.esm-bundler.js",
the index.js bundle size increases by few kb, in my case 30kb (which is minimal)
You could now add some what-if-fail and show-while-loading with defineasynccomponent