I am fairly new to Vue.js and having trouble understanding why I am getting this error:
Uncaught TypeError: Cannot read properties of undefined (reading 'contacts')
This is the method that is causing the error:
methods: {
sortContacts: () => {
return _.sortBy(self.contacts, [(contact) => {
return contact.unread;
}]).reverse();
}
}
Contacts is an array in the component data, so why would it not be able to access this?
I am providing the whole script as per request, and here it is below this text. The code is written with Vue.js and I have not included the HTML above is this seems unnecessary.
<script>
import Conversation from "../components/Conversation";
import ContactsList from "../components/ContactsList";
import { mapState } from 'vuex';
export default {
components: {Conversation, ContactsList},
data() {
return {
selectedContact: null,
messages: [],
contacts: []
}
},
computed: {
...mapState({
userId: state => state.user.id
}),
},
mounted() {
axios.get('/api/contacts')
.then((response) => {
const contacts = response.data.data;
this.contacts = _.sortBy(contacts, [(contact) => {
return contact.unread;
}]).reverse();
});
},
watch: {
userId(userId) {
Echo.private(`messages.${userId}`)
.listen('NewMessage', (e) => {
this.handleIncoming(e.message);
});
}
},
methods: {
addMessage(message) {
this.messages.push(message);
},
async logout() {
try {
axios.post("/logout");
this.$store.dispatch("logout");
this.$router.push({ name: "auth-login" });
} catch (error) {
this.$store.dispatch("logout");
this.$router.push({ name: "auth-login" });
}
},
getMessages(contact) {
this.updateUnreadCount(contact, true);
axios.get(`/api/messages/${contact.id}`)
.then((response) => {
this.messages = response.data.data;
this.selectedContact = contact;
});
},
handleIncoming(message) {
if (this.selectedContact && message.from === this.selectedContact.id) {
this.addMessage(message);
}
this.updateUnreadCount(message.from_contact, false);
},
updateUnreadCount(contact, reset) {
this.contacts = this.contacts.map((single) => {
if (single.id !== contact.id) {
return single;
}
if (reset) {
single.unread = 0;
} else {
single.unread = 1;
this.contacts = this.sortContacts();
}
return single;
});
},
sortContacts: () => {
return _.sortBy(this.contacts, [(contact) => {
return contact.unread;
}]).reverse();
}
}
}
</script>
CodePudding user response:
I made a small snippet to make the same sort.
Beyond the obvious self
mistake, I already change your sortContacts
method notation to:
sortContacts: function () {
return _.sortBy(this.contacts, [(contact) => {
return contact.unread;
}]).reverse();
}
And is working as expected.
var app = new Vue({
el: "#app",
data() {
return {
result: [{name: 'adam', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}],
};
},
methods: {
sortClick: function (){
this.result = this.sortContacts();
},
sortContacts: function (){
console.log(this.result)
return _.sortBy(this.result, [(r) => {
return r.name;
}]).reverse();
}
},
});
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
</head>
<body>
<div id="app">
{{ result }}
<button v-on:click="sortClick">Reverse</button>
</div>
</body>
</html>
Please, also verify the snippet const contacts = response.data.data;
in you mounted
section.
Normally the content of the request comes in the first data
. Make sure your content really is in the second data
attribute. A simple console.log
in request
will be fine.