Returning values in Vue template - vuejs2

I cannot get values in my template while i have the data, here is my code:
code
<template>
<div>
{{project}}
</div>
</template>
<script>
export default {
props: ['id'],
data() {
return{
project:[]
}
},
created(){
this.fetchProject();
},
methods:{
fetchProject(){
var self = this;
axios.post('/showprojectvue/' +self.id).then(res => {
self.project.push(res.data);
});
},
}
}
</script>
output
[ { "id": 33, "user_id": 2, "title": "kjfsdjowhd", "slug": "kjfsdjowhd", "body": "<p>khweihgtfihrwhtg</p>", "attachment": null, "projectclass": "sthrh", "budget": 36346, "deadline": "2018-08-24", "published": "n", "runing": "n", "payment_verified": "n", "created_at": "2018-08-05 03:43:16", "updated_at": "2018-08-05 03:43:16" } ]
i cannot use any of {{project.title}} or {{project['title']}}
How can I get out my data?

As your data is an array you need to use v-for to iterate over it.
<template>
<div v-for="obj in project">
{{obj.title}}
</div>
</template>
Example,
function callMe(){
var vm = new Vue({
el : '#root',
data : {
project : []
},
methods: {
ajaxCall(){
this.project=[{ "id": 33, "user_id": 2, "title": "kjfsdjowhd", "slug": "kjfsdjowhd", "body": "<p>khweihgtfihrwhtg</p>", "attachment": null, "projectclass": "sthrh", "budget": 36346, "deadline": "2018-08-24", "published": "n", "runing": "n", "payment_verified": "n", "created_at": "2018-08-05 03:43:16", "updated_at": "2018-08-05 03:43:16" }];
}
},
})
}
callMe()
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.11/dist/vue.js"></script>
<div id='root'>
<button type="button" #click="ajaxCall">Click ME</button>
<div v-for="obj in project">
Title: {{obj.title}}
<p>
Object:{{obj}}
</p>
</div>
</div>

Related

How Can I get a specific array id from a v-for loop input and pass it into a data store?

Here is my code
<template>
<div class="w-full bg-white mt-13">
<div class="flex flex-col mx-12 mt-8">
<div>
<table class="w-full h-auto my-12 border border-collapse table-auto">
<tr class="border">
<th v-for="i in columns" :key="i.name" class="border">
{{ i.title }}
</th>
</tr>
<tr v-for="p in getParticipants" :key="p.id">
<td class="border"></td>
<td class="border">{{ p.fullName }}</td>
<td class="border">{{ p.phone }}</td>
<td class="border">{{ p.participantId }}</td>
<td
v-for="(btn, index) in buttonCheckAtt"
:key="index"
class="border select-attendance"
>
<div>
<button
:unique-key="true"
class="w-full h-16 text-transparent"
:class="[
btn.className,
{ selected: selectedIndex === index },
]"
#click="selectedIndex = index"
>
{{ btn.btnText }}
</button>
</div>
</td>
<td class="w-16 border">
<input
ref="p.participantId"
#change="updateRemarks()"
v-model="note"
/>
</td>
</tr>
<tr></tr>
</table>
</div>
</div>
</div>
</template>
<script>
import Button from "#/components/form/Button.vue";
import { mapGetters } from "vuex";
const columns = [
{
title: "#",
},
{
title: "Name",
},
{
title: "Phone Number",
},
{
title: "ID",
},
{
title: "P",
},
{
title: "A",
},
{
title: "AP",
},
{
title: "L",
},
{
title: "Remarks",
},
];
const data = [];
export default {
components: { Button },
data() {
return {
note: null,
participantId: "abc-1",
};
},
methods: {
updateRemarks() {
let data = {
participants: [
{
participantId: this.participantId,
attendance: {
status: this.status,
note: this.note,
markBy: "organizer-id",
markMethod: "manual",
},
},
],
};
this.$store.dispatch(
"$_studyGroup/addRemarks",
{ participantData: data },
{ root: true }
);
},
},
computed: {
...mapGetters({
getParticipants: "$_studyGroup/getParticipants",
}),
},
mounted() {
this.$store.dispatch("$_studyGroup/getParticipants", {}, { root: true });
},
};
</script>
I want to use this input to this input to make patch request into my getParticipants api however it requires me to pass the participantId into the participants data in order to make patch request and I have no idea how to retrieve that participantId from the v-for loop
<input
ref="p.participantId"
#change="updateRemarks()"
v-model="note"
/>
and down below is what my getParticipants api looks like I want to pass the abc-1 and abc-2 id into the attendance in order to make patch request
getParticipants = [
{
"status": "join",
"createdAt": "2022-09-20T07:30:06.753Z",
"calendarId": "6553c8ea-0139-4802-b5d6-127e44b95412",
"email": "john#gmail.com",
"fullName": "John",
"participantId": "abc-1",
"attendance": {
"participantId" : {{participantId}},
"markBy": "organizer-id",
"markMethod": "manual",
"note": "Because of traffic jam",
"status": "Present"
},
{
"status": "join",
"createdAt": "2022-09-20T07:30:06.753Z",
"calendarId": "6553c8ea-0139-4802-b5d6-127e44b95412",
"email": "chris#gmail.com",
"fullName": "Chris",
"participantId": "abc-2",
"attendance": {
"participantId" : {{participantId}},
"markBy": "organizer-id",
"markMethod": "manual",
"note": "Because of traffic jam",
"status": "Late"
},]

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 })
}
})

Not able to access data variable in script but can in html

I have populated a data variable with an array, and can access its contents by using a v-for in the html, but I can't access any of the data in the variable within the script, and I don't know why.
var result = [{
"CatalogName": "Retro Doors",
"ItemName": "French Doors",
"ItemListPrice": "$461.00",
"ItemType": "Oak",
"ItemFeatures": [{
"Features": "Door Quantity",
"QTY": 2
},
{
"Features": "Door Hinges",
"QTY": 4
},
{
"Features": "Door Knobs",
"QTY": 1
},
{
"Features": "Door Looks",
"QTY": 1
},
{
"Features": "Glass Panes",
"QTY": 2
}
]
}];
new Vue({
el: '#app',
beforeCreate: function() {
console.log("Before Created");
},
created: function() {
console.log("Created");
this.GetItemsList();
},
beforeMount: function() {
console.log("Before Mount");
},
data: {
itemPriceList: []
},
methods: {
GetItemsList() {
this.itemPriceList = result;
}
},
mounted: function() {
console.log("Mounted");
console.log(this.ItemPriceList);
}
});
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.17/dist/vue.js"></script>
<div id="app">
{{ itemPriceList[0].CatalogName }}
<div v-for="item in itemPriceList">
{{ item.ItemName }}
<div v-for="items in item.ItemFeatures">
{{ items.Features }} : {{ items.QTY }}
</div>
</div>
</div>
You have a typo in a variable name inside mounted hook - used with capital I.
In data: itemPriceList
In mounted hook: this.ItemPriceList
Should be the same as defined inside data property.

Vue component list 2 event handling

Struggling with how to use .sync when you render components from a list. How do I handle the event emitted in my component to update the parent?
Trying to update the categorySet.gradeCategory.predictionWeight in the input.
<category-set v-for="cat in categories" v-bind:key="cat.id" v-bind:category-set="cat"></category-set>
Vue.component('category-set', {
props: ['categorySet'],
template: ' <div class="form-group">\n' +
' <label for="gradeRange" class="col-sm-2 control-label">{{ categorySet.gradeCategory.gradeCategoryName }}</label>\n' +
' <div class="col-sm-1">\n' +
' <input id="gradeRange" class="form-control" type="number" v-bind:value.number="categorySet.gradeCategory.predictionWeight" \n' +
' step="0.5" v-on:input="$emit(\'input\', $event.target.value)" > \n' +
' </div>\n' +
' </div>'
});
Fiddle: https://jsfiddle.net/rhmiller/aq9Laaew/10971/
Personally, I would do it like the following:
The component is passed the array index and the item (cat), with the item you define the item within the component, then bind the input event which then emits the complete object back to the parent with its index, then the parent sets the item back into the data.
As the Final Exam item is nulled the gradeCategory property you need to handle/recover from that as your using it in the view. Also the label is the same in the parent, so prefer to use that else it would be null if you used the gradeCategory one.
Vue.component('categorySet', {
template: '#category-set',
props: ['data', 'index'],
data() {
return {
item: {
label: this.data.label,
showInSummary: this.data.showInSummary,
gradeCategory: Object.assign({
"gradeCategoryName": null,
"groupGradeWeight": 0.0,
"predictionWeight": null,
"id": this.data.id
}, this.data.gradeCategory),
id: this.data.id
}
}
},
methods: {
inputOccurred(e) {
this.$emit('on-change', this.item, this.index)
}
}
});
//
var vm = new Vue({
el: '#app',
data() {
return {
categories: [
{
"label": "Assignments",
"showInSummary": true,
"gradeCategory": {
"gradeCategoryName": "Assignments",
"groupGradeWeight": 0.0,
"predictionWeight": null,
"id": 81
},
"id": 81
}, {
"label": "Reflections",
"showInSummary": true,
"gradeCategory": {
"gradeCategoryName": "Reflections",
"groupGradeWeight": 10.0,
"predictionWeight": null,
"id": 82
},
"id": 82
}, {
"label": "Quizzes",
"showInSummary": true,
"gradeCategory": {
"gradeCategoryName": "Quizzes",
"groupGradeWeight": 10.0,
"predictionWeight": 10.0,
"id": 83
},
"id": 83
}, {
"label": "Attendance \u0026 Participation",
"showInSummary": true,
"gradeCategory": {
"gradeCategoryName": "Attendance \u0026 Participation",
"groupGradeWeight": 0.0,
"predictionWeight": null,
"id": 84
},
"id": 84
}, {
"label": "Final Exam",
"showInSummary": true,
"gradeCategory": null,
"id": 92
}
]
}
},
methods: {
syncCategorie(value, index) {
this.categories[index] = Object.assign(this.categories[index], value);
}
}
});
<div id="app">
<category-set v-for="(cat, index) in categories" :key="cat.id" :data="cat" :index="index" #on-change="syncCategorie"></category-set>
<pre>{{ categories }}</pre>
</div>
<template id="category-set">
<div class="form-group">
<label for="gradeRange" class="col-sm-3 control-label">{{ item.label }}</label>
<div class="col-sm-1">
<input id="gradeRange" class="form-control" type="number" v-model="item.gradeCategory.predictionWeight" step="0.5" #input="inputOccurred">
</div>
</div>
</template>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.14/vue.min.js"></script>
Run the snippet your see it updates the parent fine.
You can just omit the v-on:input part when you add a .sync modifier.
:prop.sync="binding"
will effectively expands into:
:prop="binding" #update:prop="value => binding = value"
( : is just an abbreviation for v-bind: and # for v-on: )