Vue v-for _vm.item is undefined - vue.js

i'm using Quasar Framework 1.0.5, Vue 2.6, Vue-apollo.
I have a problem with v-for
In the browser console i get a error _vm.item is undefined even though the data is there.
The code works like this that in the data section i initialize my array to an empty array. Then when the user clicks vue-apollo is making a request to the backend and updates the array.
The data section:
data() {
return {
eventsByDay: []
}
},
The vue-apollo update function (where the data is loaded from the API):
I'm using the apollo option.
apollo: {
loadTermine: {
query: TermineByDayQuery,
...
result ({ data, loading, networkStatus }) {
console.info('before:');
console.info(this.eventsByDay);
this.eventsByDay = data.TermineByDayQuery;
console.info('after:');
console.table(this.eventsByDay);
},
The template (in PUG, which generates html):
q-card-section.q-mx-none.row(v-if="eventsByDay.length > 0")
q-item.col.text-left.q-pa-none
q-item-section
.text-grey-7 {{this.selectedDate | formatDate}}
p.text-black.q-mt-lg.text-weight-bold(v-for="item in eventsByDay" :key="item.id") Lorem ipsum dolor
.row
p.col.text-grey-7.q-mt-xs 07:50 Uhr
p.col.text-grey-7.q-mt-xs.text-right Ort {{eventsByDay.length}} {{item.city}}
The problem is the last {{item.city}} . There it says _vm.item is undefined. When i remove this then there is no error. Even {{eventsByDay.length}} shows the correct length of the array - 2.
The elements are there in the Array:
Any idea what i doing wrong?

Solved by removing the leading p in the template:
.text-black.q-mt-lg.text-weight-bold(v-for="item in eventsByDay" :key="item.id") Lorem ipsum dolor
Dont know why this is a problem. PUG?

Related

Vue3 reactive object not showing correct value in :rules of Vuefrom

Here is my component for Vueform elements (Textelement, checkboxgroupelement etc)
<component v-for="question, i in questions" :is="`${question.type}-element`"
:name="i" :label="question.label"
:description="question.description"
:items="question.items"
:key="i"
:placeholder="question.placeholder"
:rules="question.rule" />
All things are working correctly except for :rules which is for form validation.
Originally "questions" is an array of objects and computed method is as follows:
computed: {
questions() {
return this.data.questions?.map(q => { console.log(isReactive(q));
return { ...q, rule: [`min:${q.minchars}`, `max:${q.maxchars}`] }
})
},
},
Output shows null even if max and min chars are set correctly.
Heres an output
Please help!
I tried using reactivity on questions array so that rule gets updated , its showing updated values but in output I am getting message "must be at least null characters" issue.

Spartacus 4.2 - Type '"before"' is not assignable to type 'OutletPosition'

While trying to customize the navigation slot, we are getting the error
Type '"before"' is not assignable to type 'OutletPosition'.
This is the code we are trying.
Also have tried
[cxOutletPos]=“outletPosition.BEFORE”
Documentation referred for Spartacus 4.2 :
https://sap.github.io/spartacus-docs/outlets/#template-driven-outlets
Result should be something like custom info, followed by navigation bar as shown below:
Also, as the above method didn't work I tried retrieving data through let-model for manipulation.
Array I want to retrieve data from into our component: CategoryNavigationComponent.
But using let-model and Printing model object I can see only "uid" , "typeCode" and "flexType" but not the navigatioNode and Children.
Is there any way to retrieve Navigation bar or Children array data on the screen?
****in TS File:****
settingsSubmenu: any = [];
constructor(public component: CmsComponentData<any> )
{
this.component.data$.forEach(element => {
element.navigationNode.children.forEach(child => {
this.settingsSubmenu.push(child)
});
});
}
**in HTML File**
<ng-container *ngFor="let menuItem of settingsSubmenu">
<a mat-menu-item >{{menuItem.title}}</a>
</ng-container>
If your questions is about Typescript error, then possible two solutions:
Modify tsconfig.json to ignore Typescript error:
{
...
"angularCompilerOptions": {
...
"strictTemplates": false
}
}
Modify your code to compile without errors:
In *.component.ts file add import:
import {OutletPosition} from '#spartacus/storefront';
and define variable:
outletPosition = OutletPosition;
In *.component.html file:
[cxOutletPos]="outletPosition.BEFORE"

Avoid converting null to empty string on b-input blur

I'm facing an issue with reactivity in Vue JS 2.6.6. Not sure if it's an issue at all or I'm missing something here.
I'm hydrating an object from MySQL DB through axios getting:
resource:Object
id: 123
alt: null
file:"2a72d890d0b96ef9b758784def23faa1.jpg"
type:"jpg"
}
The form is handling the properties via v-model:
<b-input v-model="resource.alt" />
What I can see is that on blur event, besides no changes were made, the resource.alt property is being changed from null to an empty string ""
resource:Object
id: 123
alt: ""
file:"2a72d890d0b96ef9b758784def23faa1.jpg"
type:"jpg"
}
So what could be the best way to handle this? I don't think that fetching all null fields from DB as empty strings is a nice solution. I mean something like IFNULL(files.alt,'') AS alt
On the other hand, since I fetch a lot of records by doing a loop through them all and setting all null properties to empty string looks very inefficient.
What I need is to keep null properties as null or parse in some way all null properties to empty string from the beginning.
FYI, I'm using vee-validate, so I need to validate if the object has changed with pristine flag which is set to false if the object has been manipulated. This behavior is setting the flag to false because of the change from null to ""
EDIT
This is getting odd. The way I propagate the resource to local data in the component is by clicking an element from a list.
data: () => ({
files: [],
resource: {}
})
<div v-for="file in files" :key="file.id"
#click.exact="handleIndividualCheck(file)">
{{ file.file }}
</div>
methods: {
handleIndividualCheck (item) {
this.resource = { ...item }
}
}
The first time I select an item, the null property is converted to an empty string as explained.
The next times, everything works as expected
This is in fact a bootstrap-vue bug for version 2.19.0
I've reported the issue and fixes will be merged in the next release.
Link to issue: https://github.com/bootstrap-vue/bootstrap-vue/issues/6078

VueJS: :class, condition with index

I'm creating a list of (thumbnail) 2 images, and #click each image should be expanded to max-width, by adding said class ('max-w-full') to the classes. The class is added by setting the array entry with the same index nr. as the image (imgclicked[0], imgclicked[1]) in the list to 1.
data:() {
imgclicked=[0,0], //by default both are set to 'small'/not 'max-w-full'
},
the template part looks like this:
<template v-for="(image,index) in images>
<a #click="zoomImgClicked(index)">
<img :src="image.filename" :class={'max-w-full' : imgclicked[index]==1,'w-12' : imgclicked[index]==0}">
</a> // using this.imgclicked[index] gives me the error 'this.imgclicked[0] is undefined'
</template>
on click the method zoomImgClicked() ist launched:
zoomImgClicked: function(i){
if(this.imgclicked[i]==0){
this.imgclicked[i]=1
}else{
this.imgclicked[i]=0
}
},
But this is not working. If I open the vue console and change the values of imgclicked[0] manually from 0 to 1 it works (images ae being resized). Also I see the method doing it's work, when logging in the console, the values are changed from 0 to 1 and vice versa. But it's not reflected on the page #click.
Why is that?
Please read Change Detection Caveats in the Vue docs.
Vue cannot detect the following changes to an array:
When you directly set an item with the index, e.g. vm.items[indexOfItem] = newValue
When you modify the length of the array, e.g. vm.items.length = newLength
You should use the $set method for this:
this.$set(this.imgclicked, i, 1)
try with array syntax:
<img
:src="image.filename"
:class="[
{
'max-w-full': imgclicked[index]==1,
'w-12': imgclicked[index]==0
},
'static class if need'
]"
>

V-select bug while selecting elements in Vuejs

I'm building a small application in vuejs 2 where I'm using v-select package for select box, Problem I'm facing is:
I've declared v-select in my component something like this:
<div class="form-group"><label class="col-sm-2 control-label">Company name:</label>
<div class="col-sm-6">
<v-select :options="companyOptions" v-model="company_name" :on-search="getOptions" placeholder="Company name"></v-select>
</div>
</div>
So accordingly I'm having data defined as company_name, and I'm calling an axios event to get the searchable data, while the component is being loaded I'm calling index data of first 50 set for initial selection and if anybody types then I'm calling a function getOptions to get data related to the input, now suppose if somebody selects any data and then removes it again from the selection and again search with key press event the searchable data is not displayed, I can see that my axios call is working fine and I'm able to get the relevant data. but it is not displaying in dropdown as it says:
Error in render function: "TypeError: Cannot read property 'label' of null"
Which is coming from the company_name model which was selected. Following is my code in codepen
In this my axios is not working as it says mixed content:
https://codepen.io/anon/pen/Bdeqam?editors=1011' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://connect.stellar-ir.com/api/companies'. This request has been blocked; the content must be served over HTTPS.
So I'm unable to explain properly in this code set. But my code looks same as declared in codepen.
Help me out in this.
The error is because your computed values are undefined and undefined is not a string, so no string methods (toLowerCase()) are available. The response.data.model.data must look like this:
[
{
id: 1234,
name: 'example'
}, {
id: 12345,
name: 'example2'
}
]
if you get an object instead of an array push it to the array: this.serverData.push(response.data.model.data)
Replace your axios call with:
this.serverData = [
{
id: 1234,
name: 'example'
}, {
id: 12345,
name: 'example2'
}
]
to test it.
In your getOptions() method you calling loading(true or false), but your fetchIndexData() method has an asynchronous axios call. Use async/await, a callback function or a promise chain to wait for the data and show the loading indicator correctly.
On every keypress an request is send to the server i would recommend to use a debounce function.
Tipp
Line 42: https://stackoverflow.com/a/42028776/6429774
axios.post('http://connect.stellar-ir.com/api/companies', searchData).then(response => {
if(response.status === 200)
{
this.serverData = response.data.model.data
}
}).catch(error => {
console.log(error)
});