In my laravel vuejs application I have following vue to display some data inside a datatable .
For the better user experience, I have added a Show more option to load data.
<show-more :data-size="documents.length" increment-amount="5" >
<div slot-scope="{ showMore, showAmount }">
<div v-bind:class = "selectedForAction.count() === 0 ? 'h-15' : ''">
<action-bar :count="selectedForAction.count()">
<div slot="table-header" >
<!--Course -->
<div >
<selectable-all item="selectAll" :data="documents" @select="selectAll"></selectable-all>
</div>
<div >
Document
</div>
<div item="validFor">
Valid until
</div>
<div item="status">
Validity
</div>
<div >
</div>
<div >
</div>
</div>
<button v-if="selectedForAction.count() === 1" @click="editSelectedDocument" >
<span >
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" ><path d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"></path></svg>
</span>
<span >Edit</span>
</button>
<button @click="removeSelectedDocument" >
<span >
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" ><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="9" y1="9" x2="15" y2="15"></line><line x1="15" y1="9" x2="9" y2="15"></line></svg>
</span>
<span >Remove</span>
</button>
</action-bar>
</div>
<!--Certificates-->
<div v-if="documents[index] !== undefined" v-for="(i, index) in showAmount" >
<!--Certificate institute image-->
<div item="certificatedChecked" >
<div >
<div >
<selectable
v-model="selectedForAction"
:item="documents[index].id"
:ref="documents[index].id"
></selectable>
</div>
</div>
</div>
<div item="certificate">
<span :title="documents[index].name" style="cursor: help;" >{{ documents[index].name }}</span>
</div>
<!--Certificate due date-->
<div item="validFor">
<p v-if="documents[index].is_valid_forever">{{ 'Indefinite'}}</p>
<p v-else>{{ documents[index].expires_at_formatted }}</p>
</div>
<!-- Certificate status-->
<div item="status">
<status :status="documents[index].validity_status.toLowerCase()"></status>
</div>
<!--Download icon-->
<div item="download">
<a v-if="documents[index].url !== null" :href="getDocumentDownloadLocation(documents[index].id)" >
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" ><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>
</a>
</div>
<!--Preview icon-->
<div item="view">
<a v-if="documents[index].url !== null" target="_blank" :href="getDocumentPreviewLocation(documents[index].id)" >
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" ><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg>
</a>
</div>
<div >
<edit-documents-modal :document="documents[index]" :identifier="`editDocument${documents[index].id}`"></edit-documents-modal>
</div>
</div>
<div >
<!--Show more button-->
<button v-if="showAmount < documents.length" @click="showMore">
show more documents
</button>
</div>
</div>
</show-more>
Now the issue is, When I tried to run this, I get following console error and my data table is not getting displayed. Not even the headers...
[Vue warn]: Error in render: "TypeError: Cannot read properties of undefined (reading 'length')"
CodePudding user response:
Its better to use computed
property to handle these situations
computed: {
getDocumentSize() {
return this.documents ? this.documents.length : 0;
}
}
and in template, do the below change
<show-more :data-size="getDocumentSize" increment-amount="5" >
....