Cannot read property 't' of undefined when testing components with v-data-table
See original GitHub issueVersions and Environment
Vuetify: 1.1.9 Vue: 2.5.2 Vue Test Utils: 1.0.0-beta.23 Browsers: JSDom OS: High Sierra 10.13.4
Steps to reproduce
Companies.vue
<template>
<div>
<v-container grid-list-md text-xs-center>
<v-layout row wrap>
<v-flex xs12>
<v-card>
<v-data-table
:headers="headers"
:items="items"
:loading="loading"
class="elevation-1"
>
<v-progress-linear slot="progress" color="blue" indeterminate></v-progress-linear>
<template slot="headerCell" slot-scope="props">
<v-tooltip bottom>
<span slot="activator">
{{ props.header.text }}
</span>
<span>
{{ props.header.text }}
</span>
</v-tooltip>
</template>
<template slot="items" slot-scope="props">
<td>{{ props.item.name }}</td>
<td>{{ props.item.contactName }}</td>
<td>{{ props.item.contactEmail }}</td>
<td class="justify-center layout px-0">
<v-icon
small
class="mr-2"
@click="viewItem(props.item)"
>
domain
</v-icon>
<v-icon
small
class="mr-2"
@click="editItem(props.item)"
>
edit
</v-icon>
<v-icon
small
@click="deleteItem(props.item)"
>
delete
</v-icon>
</td>
</template>
<template slot="no-data">
<v-btn color="primary" flat @click="createNewCompany">
Add company
<v-icon right dark>add_box</v-icon>
</v-btn>
</template>
</v-data-table>
</v-card>
</v-flex>
<v-flex xs12>
<v-btn
color="primary"
class="white--text"
@click="createNewCompany"
>
Create New Company
<v-icon right dark>domain</v-icon>
</v-btn>
</v-flex>
</v-layout>
<ConfirmModal ref="Confirm"></ConfirmModal>
</v-container>
</div>
</template>
<script>
import vuetifyToast from 'vuetify-toast';
import { getCompanies, deleteCompany } from '@/services/database/company';
import { ConfirmModal } from '@/components/commons';
export default {
name: 'companies',
data() {
return {
headers: [
{ text: 'Company', align: 'center', value: 'name' },
{ text: 'Contact Name', align: 'center', value: 'contactName' },
{ text: 'Contact Email', align: 'center', value: 'contactEmail' },
{ text: 'Actions', value: 'name', sortable: false },
],
items: [],
loading: false,
selectedItem: null,
};
},
mounted() {
this.loadInfo();
},
methods: {
loadInfo() {
this.items = [];
this.loading = true;
getCompanies()
.then(companies => {
this.items = companies.map(c => ({
id: c.id,
name: c.value.name,
contactName: c.value.contact.name,
contactEmail: c.value.contact.email,
}));
this.loading = false;
})
.catch(() => {
this.loading = false;
vuetifyToast.error('Error getting companies');
});
},
viewItem(item) {
this.$router.push({
name: 'company',
params: { companyId: item.id, originPage: 'companies' },
});
},
editItem(item) {
this.$router.push({
name: 'companyDetail',
params: { companyId: item.id, originPage: 'companies' },
});
},
deleteItem(item) {
this.selectedItem = item;
this.$refs.Confirm.open(
`Are you sure you want to delete company ${this.selectedItem.name}?`,
this.removeCompany,
);
},
removeCompany() {
deleteCompany(this.selectedItem.id)
.then(() => {
vuetifyToast.success(`Company ${this.selectedItem.name} was deleted`);
this.items = this.items.filter(item => item.id !== this.selectedItem.id);
this.selectedItem = null;
})
.catch(() => {
vuetifyToast.error(`Error deleting company ${this.selectedItem.name}`);
});
},
createNewCompany() {
this.$router.push({
name: 'companyDetail',
params: { companyId: 'new', originPage: 'companies' },
});
},
},
components: {
ConfirmModal,
},
};
</script>
Companies.spec.js
import Vue from 'vue';
import Vuetify from 'vuetify';
import VueRouter from 'vue-router';
import flushPromises from 'flush-promises';
import { mount, createLocalVue } from '@vue/test-utils';
import VeeValidate from 'vee-validate';
import * as companiesDatabase from '@/services/database/company';
import Companies from './Companies';
Vue.config.silent = true;
const localVue = createLocalVue();
localVue.use(VueRouter);
localVue.use(Vuetify);
localVue.use(VeeValidate);
describe('Companies', () => {
const routes = [
{ path: '/', name: 'home' },
];
const router = new VueRouter({
routes,
});
let wrapper;
beforeAll(() => {
console.log('version', Vuetify.version);
const { getComputedStyle } = global;
global.getComputedStyle = function getComputedStyleStub(el) {
return {
...getComputedStyle(el),
transitionDelay: '',
transitionDuration: '',
animationDelay: '',
animationDuration: '',
};
};
});
beforeEach(async () => {
companiesDatabase.getCompanies = jest.fn();
companiesDatabase.getCompanies.mockReturnValueOnce(Promise.resolve([
{
id: '1',
value: {
name: 'name',
contact: {
name: 'contact',
email: 'email@contact.com',
},
},
},
]));
const App = localVue.component('App', {
components: { Companies },
template: `
<div data-app>
<companies />
</div>
`,
});
const mountedApp = mount(App, {
localVue,
attachToDocument: true,
router,
sync: false,
});
wrapper = mountedApp.find(Companies);
});
it('should render the companies', () => {
expect(wrapper.is(Companies)).toBe(true);
});
});
Expected Behavior
Test should pass
Actual Behavior
An error appears in the console:
TypeError: Cannot read property 't' of undefined
at VueComponent.listData (node_modules/vuetify/dist/vuetify.js:9433:47)
at Watcher.get (node_modules/vue/dist/vue.runtime.common.js:3140:25)
at Watcher.evaluate (node_modules/vue/dist/vue.runtime.common.js:3247:21)
at VueComponent.computedGetter [as listData] (node_modules/vue/dist/vue.runtime.common.js:3505:17)
at VueComponent.staticList (node_modules/vuetify/dist/vuetify.js:9452:99)
at Watcher.get (node_modules/vue/dist/vue.runtime.common.js:3140:25)
at Watcher.evaluate (node_modules/vue/dist/vue.runtime.common.js:3247:21)
at VueComponent.computedGetter [as staticList] (node_modules/vue/dist/vue.runtime.common.js:3505:17)
at VueComponent.genList (node_modules/vuetify/dist/vuetify.js:9606:29)
at VueComponent.genMenu (node_modules/vuetify/dist/vuetify.js:9662:33)
at VueComponent.genDefaultSlot (node_modules/vuetify/dist/vuetify.js:9592:26)
at VueComponent.genInputSlot (node_modules/vuetify/dist/vuetify.js:6067:22)
at VueComponent.genInputSlot (node_modules/vuetify/dist/vuetify.js:12793:94)
at VueComponent.genControl (node_modules/vuetify/dist/vuetify.js:6011:22)
at VueComponent.genContent (node_modules/vuetify/dist/vuetify.js:6006:49)
at Proxy.render (node_modules/vuetify/dist/vuetify.js:6138:17)
at VueComponent.Vue._render (node_modules/vue/dist/vue.runtime.common.js:4542:22)
at VueComponent.updateComponent (node_modules/vue/dist/vue.runtime.common.js:2786:21)
at Watcher.get (node_modules/vue/dist/vue.runtime.common.js:3140:25)
at new Watcher (node_modules/vue/dist/vue.runtime.common.js:3129:12)
at mountComponent (node_modules/vue/dist/vue.runtime.common.js:2793:3)
at VueComponent.Object.<anonymous>.Vue.$mount (node_modules/vue/dist/vue.runtime.common.js:7997:10)
Reproduction Link
Additional Comments:
Looking at the stacktrace the following line in the vuetify.js file is the one having the issue:
noDataText: this.$vuetify.t(this.noDataText),
Thanks in advance for the help
Issue Analytics
- State:
- Created 5 years ago
- Reactions:7
- Comments:11 (3 by maintainers)
Top Results From Across the Web
Cannot read property 't' of undefined using Vuetify and Laravel
You need to create an instance of Vuetify. e.g.: new Vue({ el: '#app', vuetify: new Vuetify() }). This is documented here, though they...
Read more >Laravel vuejs 'Cannot read property of data' error-Vue.js
Coding example for the question Laravel vuejs 'Cannot read property of data' ... You can, for example, add it to data() ... And...
Read more >cannot read properties of undefined (reading 'dtinstance')
I am trying to add a new button to datatable DOM in angular using renderer2. But its triggering an error in runtime saying....
Read more >Jest: TypeError: Cannot read property 'default' of undefined
Vue CLI bundles Jest as its default test runner. All is fine and good until one day, running your unit tests you get...
Read more >LWC Jest test can't set @api array/object
I have and array @api property and can't set it in test. ... We'd need to see the component controller as well to...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Simply
instead
Polluting global Vue instance is a terrible idea.