Vue,js Display data from json - vue.js

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>

Related

Vue js dynamic v-model for form which is rendered with v-for

I have 1 check box group and 9 radio button groups, and i need v-model for each group but i do not know how to put 9 differed data properties there.
My data looks like this:
data() {
return{
servicesId: [],
personId: '',
incomeId:'',
extraIncomeId: '',
pdvId: '',
paymentId: '',
clientId: '',
cashRegisterId: '',
eBankingId: '',
}
}
In template is like this:
<div v-for="data in formData" :key="data.id">
<h5>{{data.question_text}}</h5>
<div class="form-check" v-for="text_o in data.question_options" :key="text_o.id">
<input class="form-check-input"
:type="data.question_type.type"
:value="text_o.id" :id="text_o.id"
v-model="[HERE GOES "9 "data props"]">
<label class="form-check-label" :key="text_o.id" :for="text_o.id"> {{text_o.option_text}
</label>
</div>
</div>
Here is part of (because it is long, i can post everything from it if you want)formData array:
{
"id": 1,
"question_type_id": 1,
"title": "new ent",
"question_text": "Planirate da se bavite:",
"created_at": "2021-10-12T13:42:17.000000Z",
"updated_at": "2021-10-12T13:42:17.000000Z",
"question_options": [
{
"id": 1,
"question_id": 1,
"option_text": "Uslugama",
"price": 40,
"created_at": "2021-10-12T13:44:40.000000Z",
"updated_at": "2021-10-12T13:44:40.000000Z"
},
{
"id": 2,
"question_id": 1,
"option_text": "Trgovinom",
"price": 60,
"created_at": "2021-10-12T13:46:53.000000Z",
"updated_at": "2021-10-12T13:46:53.000000Z"
},
{
"id": 3,
"question_id": 1,
"option_text": "Proizvodnjom",
"price": 80,
"created_at": "2021-10-12T13:47:22.000000Z",
"updated_at": "2021-10-12T13:47:22.000000Z"
}
],
"question_type": {
"id": 1,
"type": "checkbox",
"created_at": "2021-10-12T13:40:17.000000Z",
"updated_at": "2021-10-12T13:40:17.000000Z"
}
}
Thanks.
If you want your values to be a part of data, you can create an object that will contain your form data, like this:
data() {
return {
formValue: {
servicesId: [],
personId: "",
incomeId: "",
extraIncomeId: "",
pdvId: "",
paymentId: "",
clientId: "",
cashRegisterId: "",
eBankingId: "",
},
}
}
after adding that object, just add a name to your form data object like this:
formData: [
{
id: 1,
question_type_id: 1,
title: "new ent",
question_text: "Planirate da se bavite:",
created_at: "2021-10-12T13:42:17.000000Z",
updated_at: "2021-10-12T13:42:17.000000Z",
name: "servicesId", <-- modified part
question_options: [...]
}
]
and now you can use that name to dynamically access your formValue object which is a part of data:
<div v-for="data in formData" :key="data.id">
<h5>{{ data.question_text }}</h5>
<div
class="form-check"
v-for="text_o in data.question_options"
:key="text_o.id"
>
<input
class="form-check-input"
:type="data.question_type.type"
:value="text_o.id"
:id="text_o.id"
v-model="formValue[data.name]" <-- modified part
/>
<label class="form-check-label" :key="text_o.id" :for="text_o.id">
{{ text_o.option_text }}
</label>
</div>
</div>
Hope this approach helps you, you will have your values in data, they won't be there as separate properties, but they will be a part of a wrapper object named formValue

two differents arrays inside one component VueJs

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>

How to pass data from api to a vue method

I have the following data
"meta": {
"total_count": 17
},
"items": [
{
"id": 80,
"meta": {
"type": "",
"detail_url": "",
"html_url": "",
"slug": "",
"first_published_at": ""
},
"title": "some title",
"image": {
"id": 46,
"meta": {
"type": "wagtailimages.Image",
"detail_url": "some url",
"download_url": "/media/original_images/im.png"
},
"title": "im.png",
"width": 100,
"height": 80
},
}
]
Now if I try to get the width of an image inside :src attribute it works but if I try to pass it to a method it doesn't
, a snippet of the HTML code is:
<li v-for="(item, index) in response_data">
<a v-bind:href="item.meta.html_url">
<div class="icon" :class="classObject(item.image.width,item.image.height)">
<img v-if="item.image" v-bind:src="item.image.meta.download_url" alt=""/>
<img v-else src="{% static 'images/logo-dummy.svg' %}" alt="logo-dummy.svg"/>
</div>
where classObject is a method that compares the width and the height, I tried also to make it a computed property, the above code doesn't work but if for example I wrote
<img v-if="item.image" v-bind:src="item.image.width">
I can see the width inside the src attribute, what am I doing wrong?
Edit: classObject code is the following
classObject: function (width, height) {
if (width > height) return 'icon1'
return 'icon2'
},
The problem I encountered was because sometimes there was no image at all, otherwise the code is correct so now I just check if there's an image like this
<div v-if="item.image" :class="classObject(item.image.width,item.image.height)">
<img v-bind:src="item.image.meta.download_url" alt=""/>
</div>

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.

How to read deep JSON data using Vuejs and Axios

How would I read deep JSON data nested deep inside a file? I've tried different methods and can't seem to get this to work.
<template>
<div>
<div v-for="edu in info" :key="edu">
<div>{{ edu.section.title }}</div> // this is what im trying to get to work
</div>
<div class="card container">
{{ info }}
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
info: null
}
},
mounted() {
axios
.get('./calculus.json') // Data Below
.then(response => (this.info = response.data.edu))
.catch(error => console.log(error))
}
}
</script>
My JSON looks like this:
{
"edu": {
"1": {
"title": "Title One",
"subtitle": "Subtitle One",
"description": "Description One",
"section": {
"1": {
"title": "Section One Title",
"content": "Section One Content"
}
}
},
"2": {
"title": "Title Two",
"subtitle": "Subtitle Two",
"description": "Description Two",
"section": {
"1": {
"title": "Section One Title",
"content": "Section One Content"
}
}
}
}
}
How can I use vue-for and get the data inside the section to get it to display under the title? For example: title, section>title, section>subtitle, etc.
Given each section is also an object with weird numeric keys, you can iterate them in the same way you do info.
I would also advise you to use identifiable values instead of the entire edu object in your :key bindings.
<div v-for="(edu, eduId) in info" :key="eduId">
<div v-for="(section, sectionId) in edu.section" :key="sectionId">
{{ section.title }}
</div>
</div>
If possible, I would alter the format of your JSON data to use actual arrays instead of objects with numeric keys.
One way to browse your object deeply is to cumulate v-for on your object (and children) entries.
ie:
<div v-for="([category, books], catkey) in Object.entries(info)" :key="`category-${catkey}`">
<div>{{ category }} :</div>
<div v-for="([num, book], numkey) in Object.entries(books)" :key=`book-${catkey}-${numkey}`>
<div v-for="([field, value], valkey) in Object.entries(book)" :key=`field-${catkey}-${numkey}-${valkey}`>
{{ field }} : {{ value }}
</div>
</div>
</div>
If you find it too verbose, you may try to flatten your computed data to have the following structure:
[
{
"category": "edu",
"id": "1",
"title": "Title One",
"subtitle": "Subtitle One",
"description": "Description One",
"section": {
"1": {
"title": "Section One Title",
"content": "Section One Content"
}
}
}
]