How to pass data from api to a vue method - vue.js

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>

Related

Horizontal Scrolling And Only Date is not working in my Data table in Asp .NET 6 Web App

Here, I am using "datatables" for my asp.net 6 web app. everything is working except "Horizontal-Scrolling" & "Only Date Property" I know that I am doing some wrong here, so please help me to solve this issue. and Thanks in advance.
My related table js file, view, index and model are given below:
"btbPending.js" is given below:
Here, I use "scrollX" for the horizontal scroll bar. But it didn't show the scroll option rather than the data table taking its extra space and looks so ugly. So where I use the "scrollX" function ?
And also I use "render: $.fn.dataTable.render.moment('x','DD/MM/YYYY')" for showing the date only property but it shows "invalid Date" in my data table. Now, also I need to know how to show this "Date-Only" property in my Data table.
var dataTable;
$(document).ready(function () {
$('#tblData').DataTable({
"scrollX": true,
});
loadDataTable();
});
function loadDataTable() {
dataTable = $('#tblData').DataTable({
"ajax": {
"url": "/Admin/BTBPending/GetAll"
},
"columns": [
{ "data": "supplierSelectList.supplier", "width": "15%" },
{ "data": "countrySelectList.country", "width": "15%" },
{ "data": "itemSelectList.item", "width": "15%" },
{ "data": "value", render: $.fn.dataTable.render.number(',', '.', 2, '$') , "width": "15%" },
{ "data": "piNo", "width": "15%" },
{ "data": "shipDate", render: $.fn.dataTable.render.moment('x','DD/MM/YYYY'), "width": "15%" },
{ "data": "buyerSelectList.buyer", "width": "10%" },
{ "data": "supplierSelectList.supplier", "width": "15%" },
{ "data": "countrySelectList.country", "width": "15%" },
{ "data": "itemSelectList.item", "width": "15%" },
{ "data": "value", render: $.fn.dataTable.render.number(',', '.', 2, '$'), "width": "15%" },
{ "data": "piNo", "width": "15%" },
{ "data": "shipDate", render: $.fn.dataTable.render.moment('x', 'DD/MM/YYYY'), "width": "15%" },
{ "data": "buyerSelectList.buyer", "width": "10%" },
]
});
}
"BTBPending" Index :
<div class="card-body">
<div class="tab-content">
<div class="tab-pane fade show active" role="tabpanel">
<div class="mb-1">
<table id="tblData" class="table table-bordered table-hover table-sm align-middle m-0" style="width:100%">
<thead class="" style="text-align:center;background-color: #17A2B8">
<tr>
<th>Supplier</th>
<th>Country</th>
<th>Item</th>
<th>Value</th>
<th>PI</th>
<th>Ship Date</th>
<th>Buyer</th>
<th>Supplier</th>
<th>Country</th>
<th>Item</th>
<th>Value</th>
<th>PI</th>
<th>Ship Date</th>
<th>Buyer</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>

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

Checking if something exists in json in Vue

I've got a json API that I'm using like this:
[{
"name": "Thing",
"id": 1234,
"total": 1,
"stock": [
{
"size": "Small",
"id": 1,
"count": 10
},{
"size": "Medium",
"id": 2,
"count": 5
},{
"size": "Large",
"id": 3,
"count": 5
}
]
}]
I'm looping over these in Vue, but want to check if anything exists in the 'stock' element outside of the v-for loop.
I can use v-if to check if the overall json exists, but can't seem to narrow it down to checking if the stock element contains anything.
Any pointers?
What about a v-if & v-else condition on the length of the stocks array? If the length is greater than zero we have stocks, so display them, else, display a message. Something like this.
Vue.component('your-component', {
template:
`
<div v-for="(item, i) in items" :key="i">
<p>{{ item.name }}<p>
<p>{{ item.id }}<p>
<div v-if="item.stock && item.stock.length > 0">
<p v-for="(stock, j) in item.stock" :key="j">
There'are {{ stock.count }} of size {{ stock.size }}.
<p>
</div>
<div v-else>
Ops... stocks not available.
</div>
</div>
`,
data () {
return {
items: []
}
},
created () {
fetch('your-api')
.then((res) => res.json())
.then((res) => { this.items = res })
}
})

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"
}
}
}
]

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>