two differents arrays inside one component VueJs - vue.js

Hello i wan't to loop two differents arrays inside one component like this
operationMep= [
{
"id": 15525205,
"type": "mise_en_prep",
"orderOperationSkus": [
{
"id": 24339529,
"orderSku": {
"id": 11747818,
"referenceMep": "MB0153",
"tax": 20,
"size": "M"
}
}
}
]
operationInvoice= [
{
"id": 16525205,
"type": "invoice",
"orderOperationSkus": [
{
"id": 24339529,
"orderSku": {
"id": 11747818,
"referenceInvoice": "MB0153"
}
}
}
]
<div v-for="itemMep in operationMep">
<my-template
v-for="itemVoice in operationInvoice"
:size="itemMep.size"
:invoice="itemVoice.referenceInvoice">
</my-template>
</div>
it's possible to do that because i have 2 loop inside this component and i want to add a condition if operation invoice is null just loop operationMep. thank you

If I understand correctly, you want to avoid rendering the nested <my-template> if operationInvoice is null.
You could wrap the nested v-for loop with v-if="operationInvoice":
<div v-for="itemMep in operationMep">
<template v-if="operationInvoice">
<my-template
v-for="itemVoice in operationInvoice"
:size="itemMep.size"
:invoice="itemVoice.referenceInvoice">
</my-template>
</template>
<!-- other markup here -->
</div>

Related

return unique values from array in vuejs

I am using Vuejs and Vuex to return an array of item objects. The items can be submitted to the database with the same name multiple times. I need to create a list of unique item names in an array in Vuejs.
from map getters below all Items returns an array of objects that looks like
[
{"name": "item one", "number": "001", "size": "4000kb"}
{"name": "item two", "number": "002", "size": "5000kb"}
{"name": "item three", "number": "003", "size": "6000kb"}
]
methods: {
...mapActions(["fetchItems"])
},
computed: {
...mapGetters(["allItems"]),
itemNames: function() {
return [...new Set(this.allItems.name)]
}
},
created() {
this.fetchItems(),
this.itemNames()
},
In computed properties itemNames if I take off the .name [..new Set(this.allItems)]
the array returns the complete objects - how can I just pull the name out to a list?
The v-for does not return the array
<v-list-item v-for="(itemName, index ) in itemNames" :key="index">
<v-list-item-content> {{ itemName }}</v-list-item-content>
</v-list-item>
Thanks for any help.
I solved this one in computed properties by mapping the items to a new array like so
itemNames: function() {
return [...new Set(this.allItems.map(x => x.item.Name))]
}

v-model an array using vue map state

I am working on creating custom fields in my application. I am allowing clients to define custom fields for various objects (ie. Initiative) and displaying them when updating or creating that object.
In my state I define the object being modified or added:
(initiatives.js)
addEditInitiative: {
name: '',
description: '',
product_name: '',
product_id: '',
quarter: '',
year: '',
custom_fields: []
},
the custom_fields array is filled with the custom fields defined for initiatives. For example, in the json response from the database, the custom fields array will include something like this...
"payload": [
{
"id": "5dc840c3d27a6e47b9baec33",
"cid": "5d8502a2a284b46f3621f389",
"name": "2",
"description": "",
"product_name": "Maps",
"product_id": "5d86509ee24692444d84b155",
"quarter": "Q2",
"year": "2019",
"custom_fields": [
{
"id": "5db8ec9fee8040e9b6dfad87",
"cid": "5d8502a2a284b46f3621f389",
"name": "Test",
"type": "text",
"form": "initiative",
"value": ""
},
{
"id": "5dba0bcedf9cbf185683ecca",
"cid": "5d8502a2a284b46f3621f389",
"name": "test2",
"type": "text",
"form": "initiative",
"value": ""
}
]
}
]
}
I am trying to edit the value for each of those custom fields through vuex map fields, or if that doesnt work, some other way that isn't causing the error I am getting now. I am not mutating the state. I am directly using v-model on the state.
(Vue Component)
<v-item v-for="(field, index) in initiativeFields"
v-bind:index="index"
v-bind:key="field.id">
<v-text-field v-if="field.type = 'text'"
:label="field.name"
type="text"
v-model="addEditInitiative.custom_fields[index].value">
</v-text-field>
</v-item>
I am not sure how to replace v-model="addEditInitiative.custom_fields[index].value" with something that will mutate the state. I have been using https://github.com/maoberlehner/vuex-map-fields for this for simple fields. For Example,
(Vue Component)
...mapFields('initiative', [
'addEditInitiative.name',
'addEditInitiative.description',
'addEditInitiative.product_name',
'addEditInitiative.product_id',
'addEditInitiative.quarter',
'addEditInitiative.year',
]),
Try using multiple row fields.
https://github.com/maoberlehner/vuex-map-fields#multi-row-fields
v-model="test" is actually just a shorthand for :value="test" #input="test = arguments[0]" (or :value="test" #input="test = $event.target.value" for native components like input).
You can use this to your advantage to refactor your code a bit to something like this:
<v-item v-for="(field, index) in initiativeFields"
v-bind:index="index"
v-bind:key="field.id">
<v-text-field v-if="field.type = 'text'"
:label="field.name"
type="text"
:value="addEditInitiative.custom_fields[index].value"
#input="updateValue($event, index)">
</v-text-field>
</v-item>
And in your updateValue method you could update the store with an action/mutation.

VueJS - Auto create a A-Z letters list from the data

Is it possible to create a A-Z letters list (like this) from the data from a API and Vue to be able to determine if a property in a data contains a name that starts with what letter. If the data doesn't contain a specific letter name then remove/disable the href attribute from the letter anchor tag.
In the linked example, letters K, X and Z are missing coz they don't have the data
JSON
[
{
"id": 77,
"link": "http://my-site/cosmoquotes/authors/anonymous/",
"name": "Anonymous",
"slug": "anonymous"
},
{
"id": 72,
"link": "http://my-site/authors/ferdinand-marcos/",
"name": "Ferdinand Marcos",
"slug": "ferdinand-marcos"
},
{
"id": 75,
"link": "http://my-site/authors/john-f-kennedy/",
"name": "John F. Kennedy",
"slug": "john-f-kennedy"
},
{
"id": 67,
"link": "http://my-site/authors/john-maxwell/",
"name": "John Maxwell",
"slug": "john-maxwell"
}
]
Component
export default {
data() {
return {
authorsRequest: {
type: 'authors',
params: {
per_page: 100
}
},
}
},
computed: {
authors () {
return this.$store.getters.requestedItems(this.authorsRequest)
},
},
methods: {
getAuthors() {
return this.$store.dispatch('getItems', this.authorsRequest)
},
},
created() {
this.getAuthors()
}
}
So as per the returned data, only the letters 'A', 'F' and 'J' should be clickable/displayed.
I managed to do it like this,
unfortunatly it needs the authors array and the conditionnal function to be outside of the Vue component because I couldn't find how to pass argument to computed values
But since I'm new to vue (didn't even finish reading the introduction) I'm sure there has to be a better solution
EDIT: found the way to have the function in the component with methods, I could then move the data in the component too
let a = new Vue({
el: "#selector",
data: {
authors: [{"id": 77,"link": "http://my-site/cosmoquotes/authors/anonymous/","name": "Anonymous","slug": "anonymous"},{"id": 72,"link": "http://my-site/authors/ferdinand-marcos/","name": "Ferdinand Marcos","slug": "ferdinand-marcos"},{"id": 75,"link": "http://my-site/authors/john-f-kennedy/","name": "John F. Kennedy","slug": "john-f-kennedy"},{"id": 67,"link": "http://my-site/authors/john-maxwell/","name": "John Maxwell","slug": "john-maxwell"}]
},
computed: {
// there have to be a way to get this array without doing it like this but I don't know it ^^
letters() {
let letters = []
for(let i = "A".charCodeAt(0); i <= "Z".charCodeAt(0); i++) {letters.push(String.fromCharCode([i]))}
return letters
}
},
methods: {
// you may add a toUpperCase()/toLowerCase() if you're not sure of the capitalisation of you datas
isALink(letter) {
return this.authors.some(aut => aut.name.startsWith(letter))
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="selector">
<template v-for="letter in letters">
<a v-if="isALink(letter)" :href="letter">{{ letter }}</a>
<a v-else>{{ letter }}</a>
</template>
</div>
you can set the unique name as the id of dom. when you click to letter X, just get the first name start with X , and use getElementById to match the dom and scroll to the dom.

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>

Vue,js Display data from json

How to fetch the product name from the below result. I tried
<div class="card-divider">
{{ post.basic_info.prod_name }}
</div>
But it is not working
Many thanks
{
"name":"Test ProductCategory",
"updated":"2018-07-16 15:00:03",
"12":{
"basic_info":{
"prod_name":"Product name 1",
"status":"Active",
"image":""
},
},
"13":{
"basic_info":{
"prod_name":"Product name 2",
"status":"Active",
"image":""
},
}
}
Try this:
{{ post["12"].basic_info.prod_name }}
Your JSON have two same keys, so you will receive Product name 2 only, because, latter will replace previous key "12"
My suggestion, modify data to receive something like:
{
"name": "Test ProductCategory",
"updated": "2018-07-16 15:00:03",
"data": [
{
"basic_info": {
"prod_name": "Product name 1",
"status": "Active",
"image": ""
},
}, {
"basic_info": {
"prod_name": "Product name 2",
"status": "Active",
"image": ""
},
}
]
}
you can loop over data and get basic_info.prod_name then your html will be like:
<div class="card-divider" v-for="obj in post.data">
{{ obj.basic_info.prod_name }}
</div>