Vue js error push with method sendMessage - javascript

I have method:
props: ['convId'],
data() {
return {
messages: [],
newMessage: ''
};
},
methods: {
sendMessage() {
axios.post('/sendMessage/' + this.convId, { message: this.newMessage })
.then(response => this.messages.push(response.data.data));
this.messages.push(newMessage);
this.newMessage = '';
console.log(this.messages.id); //TypeError: Cannot read property 'id' of undefined
}
},
When I try get updated this.messages. I get undifined properties of this object. Why?
In request I return object:
{"body":"test","user_id":1,"type":"text","conversation_id":1,"updated_at":"2018-06-04 13:15:27","created_at":"2018-06-04 13:15:27","id":16,"conversation":{"id":1,"private":1,"data":null,"created_at":"2018-06-01 12:54:33","updated_at":"2018-06-04 13:15:27","users":[{"id":1,"name":"Axer","email":"test#gmail.com","created_at":"2018-06-01 12:35:37","updated_at":"2018-06-01 12:35:37","pivot":{"conversation_id":1,"user_id":1,"created_at":"2018-06-01 12:54:33","updated_at":"2018-06-01 12:54:33"}},{"id":2,"name":"Testumus","email":"teadasdasd#gmail.com","created_at":"2018-06-01 12:46:30","updated_at":"2018-06-01 12:46:30","pivot":{"conversation_id":1,"user_id":2,"created_at":"2018-06-01 12:54:33","updated_at":"2018-06-01 12:54:33"}}]}}
How I can fix this?

You haven't specified newMessage variable. Maybe you wanted to insert this.newMessage.
If you are trying to get the result thats been insert maybe you can return the database data into the response and then push in message , that way you'll be able to get id and other column which you are using to log it out on console.
axios.post('/sendMessage/' + this.convId, { message: this.newMessage })
.then((response) {
this.messages.push(response.data.data) // Fetched message from server
this.newMessage = '';
console.log(this.messages.id);
})

props: ['convId'],
data() {
return {
messages: [],
newMessage: ''
};
},
methods: {
sendMessage() {
axios.post('/sendMessage/' + this.convId, { message: this.newMessage })
.then((response) {
this.messages.push(response.data.data);
this.messages.push(newMessage);
this.newMessage = '';
console.log(this.messages.id);
});
}
},
Try this.

Related

How can I use data defined in data() in other methods in Vue js?

First I defined Types, Severities, and Statuses as [] and returned them in data().
Then I filled them with data in the methods getTypes(), getSeverities(), and getStatuses().
I want to use Types, Severities, and Statuses in the method getName()(just has console.log() as an example for now).
I noticed when debugging getNames(), type in the second for loop is undefined. Is it because the method is using Type before it was assigned values in getTypes()? How can I make it work?
Note: Types, Severities, and Statuses do get assigned values in the methods getTypes(), getSeverities(), and getStatuses(), the issues is how to use the data in other methods.
<script>
import IssuesTable from '../MyIssuesPage/IssuesTable.vue'
import AddIssue from '../MyIssuesPage/AddIssue.vue'
import axios from 'axios'
export default {
props: ['id', 'project', 'issuesList', 'index'],
components: { IssuesTable, AddIssue },
data() {
return {
Issues: this.issuesList[this.index],
tab: null,
items: [{ tab: 'Issues' }, { tab: 'Calender' }, { tab: 'About' }],
Types: [],
Severities: [],
Statuses: [],
}
},
setup() {
return {
headers: [
{ text: 'Title', value: 'title' },
{ text: 'Description', value: 'description' },
{ text: 'Estimate', value: 'time_estimate' },
{ text: 'Assignees', value: 'userid' },
{ text: 'Type', value: 'issueTypeId' },
{ text: 'Status', value: 'issueStatusId' },
{ text: 'Severity', value: 'issueSeverityId' },
],
}
},
mounted() {
this.getTypes(), this.getSeverities(), this.getStatuses(), this.getNames()
},
methods: {
getTypes() {
axios
.get('http://fadiserver.herokuapp.com/api/v1/my-types')
.then(response => {
this.Types = response.data
})
.catch(error => {
console.log(error)
})
},
getSeverities() {
axios
.get('http://fadiserver.herokuapp.com/api/v1/my-severities')
.then(response => {
this.Severities = response.data
})
.catch(error => {
console.log(error)
})
},
getStatuses() {
axios
.get('http://fadiserver.herokuapp.com/api/v1/my-status')
.then(response => {
this.Statuses = response.data
})
.catch(error => {
console.log(error)
})
},
getNames() {
for (var issue of this.Issues) {
for (var type of this.Types) {
if (issue.issueTypeId == type.id) console.log('test')
}
}
},
},
}
</script>
First of all, use created() instead of mounted() for calling methods that fetch data.
Next, you need to call getNames() only after all fetch methods complete.
created() {
this.getTypes()
.then(this.getSeverities())
.then(this.getStatuses())
.then(this.getNames());
}
In order to chain methods like this you need to put return statement before each axios like this
getTypes() {
return axios
.get("https://fadiserver.herokuapp.com/api/v1/my-types")
.then((response) => {
this.Types = response.data;
})
.catch((error) => {
console.log(error);
});
}
In this component, I see you are receiving issuesList and index props from the outside. I cannot know those values but you can console.log both of them inside created() and see what is happening because issuesList[index] is undefined.
That probably means issuesList is an array and that index does not exist in that array.

Vue js: compare elements in the array

in my code below i'm trying to check if the entered email is NOT exists in the API data this.users.email
but it giving me error: can't read email of undefined.However, when i console.log(this.users) i can see all my data , but when i console.log(this.users.email) it giving me undefined, any idea on how to solve it?
export default {
data() {
return {
error: "",
message:"",
users:[],
Reset: false,
login: {
email: "",
password: "",
},
SendEmail:{
email:"",
}
};
},
methods: {
Submit(){
try {
questionService.RequestResetPassword(this.SendEmail).then((response) => {
console.log(response);
});
}
catch (e) { if(!this.sendEmail.email.includes(this.users.email)){ //error here
this.error="enter an existing email";
}}
}
},
mounted: function () {
questionService.getAllUsers().then((jsonData) => {
this.users = jsonData.data.response;
console.log(this.users) // can appear properly
console.log(this.users.email) //undefined
})}
};

Cannot read property 'affected_rows' of undefined when trying to run an Hasura mutation

I'm using apollo within my vue.js application, I'm currently trying to remove an object by running a mutation, here is the code :
this.$apollo.mutate({
mutation: require("../graphql/deleteTag.gql"),
variables: {
id: idToDelete,
},
update: (store, { data: { delete_tags } }) => {
if (delete_tags.affected_rows) {
const data = store.readQuery({
query: require("../graphql/fetchDevices.gql"),
});
data.device_id_to_tag_id = data.device_id_to_tag_id.filter((x) => {
return x.id != tag.device_id_to_tag_id.id;
});
store.writeQuery({
query: require("../graphql/fetchDevices.gql"),
data,
});
}
},
});
And my deleteTag.gql file :
mutation delete_tags($id: Int!){
delete_extras_taggeditem(where: { id: { _eq: $id } }) {
affected_rows
}
}
But when I run this the following error appears :
I don't really know what's going on because I followed the Hasura vue.js documentation...
Thanks in advance for your help !
You can specify the name of the returned key in graphql if you want your result data to be called just delete_extras instead of delete_extras_taggeditem:
mutation delete_tags($id: Int!){
delete_extras: delete_extras_taggeditem(where: { id: { _eq: $id } }) {
affected_rows
}
}
but right now, you query do not return you a
I believe you are missing optimisticResponse parameter in mutate. the "update" function takes 2 passes - first with data from optimisticResponse, and then the data from the actual mutation response.
e.g. something like...
this.$apollo.mutate({
mutation: require("../graphql/deleteTag.gql"),
variables: {
id: idToDelete,
},
optimisticResponse: {
delete_extras_taggeditem: {
__typename: 'extras_taggeditem',
id: -1,
affected_rows
}
},
update: (store, { data: { delete_extras_taggeditem } }) => {
if (delete_extras_taggeditem.affected_rows) {
const data = store.readQuery({
query: require("../graphql/fetchDevices.gql"),
});
data.device_id_to_tag_id = data.device_id_to_tag_id.filter((x) => {
return x.id != tag.device_id_to_tag_id.id;
});
store.writeQuery({
query: require("../graphql/fetchDevices.gql"),
data,
});
}
},
});
https://apollo.vuejs.org/guide/apollo/mutations.html#server-side-example
Also, generally speaking I would always return id in your responses back for any level of resource. Apollo relies on __typename + id to maintain and manipulate its cache.

Passing variables from within VueJS components

I am new to VueJs and Laravel. I am trying to build a chat app following this tutorial, and my problem is that I am not able to pass a CONTACT variable (object type) from ChatApp.vue to Conversation.vue. The console gives this error
[Vue warn]: Invalid prop: type check failed for prop "contact". Expected Object, got Null
found in ---> <MessageFeed> at resources/js/officer/components/MessageFeed.vue
<Conversation> at resources/js/officer/components/Conversation.vue
<ChatApp> at resources/js/officer/components/ChatApp.vue
<Root>
first the variable has to pass through ChatApp to Conversation and then to MessageFeed. I tried printing it on console, in ChatApp.vue, it printed the variable's property i.e. name but when I try to print it in Conversation.vue, it says it is null and also gives the above error.
please see the code below:
ChatApp.vue
<template>
<div class="chat-app">
<Conversation :contact="selectedContact" :messages="messages" #new="saveNewMessage"/>
<ContactsList :contacts="contacts" #selected="startConversationWith"/>
</div>
</template>
<script>
import Conversation from "./Conversation";
import ContactsList from "./ContactsList";
const axios = require('axios');
export default {
props: {
user: {
type: Object,
required: true
}
},
data() {
return {
selectedContact: null,
messages: [],
contacts: []
}
},
mounted() {
Echo.private(`messages.${this.user.id}`)
.listen('NewMessage', (e) => {
this.handleIncoming(e.message);
});
console.log(this.user);
axios.get('/officer/contacts')
.then((response) => {
this.contacts = response.data;
console.log("chatapp1: " + this.contacts[0].name);
})
.catch((error) => {
// handle error
console.log(error);
});
},
methods: {
startConversationWith(contact) {
axios.get(`/officer/conversation/${contact.id}`)
.then((response) => {
this.message = response.data;
this.selectedContact = contact;
console.log("chatapp: " + this.selectedContact.name);
});
},
saveNewMessage(message) {
this.messages.push(message);
},
handleIncoming(message) {
if (this.selectedContact && message.from === this.selectedContact.id) {
this.saveNewMessage(message);
return;
}
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;
return single;
})
}
},
components: {Conversation, ContactsList}
}
Conversation.vue
<template>
<div class="conversation">
<h1>{{ contact ? contact.name : 'Select a Contact' }}</h1>
<MessagesFeed :contact="contact" :messages="messages"/>
<MessageComposer #send="sendMessage"/>
</div>
</template>
<script>
import MessagesFeed from './MessageFeed';
import MessageComposer from './MessageComposer';
export default {
props: {
contact: {
type: Object,
default: null
},
messages: {
type: Array,
default: []
}
},
mounted() {
console.log("conversation: "+this.contact);
},
methods: {
sendMessage(text) {
if (!this.contact) {
return;
}
console.log(text);
axios.post('/conversation/send', {
contact_id: this.contact.id,
text: text
}).then((response) => {
this.$emit('new', response.data);
})
}
},
components: {MessagesFeed, MessageComposer}
}
MessageFeed.vue
<template>
<div class="feed" ref="feed">
<ul v-if="contact">
<li v-for="message in messages" :class="`message${message.to == contact.id ? 'sent' : 'received'}`"
:key="message.id">
<div class="text">
{{message.text}}
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
contact: {
type: Object,
required: true
},
messages: {
type: Array,
required: true
}
},
methods: {
scrollToBottom() {
setTimeout(() => {
this.$refs.feed.scrollTop = this.$refs.feed.scrollHeight - this.$refs.feed.clientHeight;
}, 1);
}
},
watch: {
contact(contact) {
this.scrollToBottom();
},
messages(messages) {
this.scrollToBottom();
}
}
}
please, let me know what am I missing here.
Because you konfigurated it to be an Object but you declared it on the initial state as null
selectedContact: null
That should be an object
It should look something like this i guess:
selectedContact: {
id:0
}
I fixed the issue.
This was due to axios.get() response thing. It was fetching data from database after a couple of minutes and the Conversation.vue and ContactList.vue were mounting immediately so they were not getting data.
With the help of my friend, it was fixed by loading the component only when axios have got all the contactlist from database and the very first contact have been passed to the Conversation.vue component i.e using v-if property of component.

vue js Cannot read property 'data' of undefined*

I am new to vue js.
this.comments.unshift(response.body.data); is not working.
I did not use json() like this.comments.unshift(response.json().data); and this.comments = response.json().data; because using json() does not show any comments. I just searched and someone mentioned to use 'body' instead of json().
Saving a comment in database is working. Only problem is showing a new comment is not working without refresh page.
These are error messages
[Vue warn]: Error in render function: "TypeError: Cannot read property 'data' of undefined"
TypeError: Cannot read property 'data' of undefined
Thank you very much.
<script>
export default {
data () {
return {
comments: [],
body: null
}
},
props: {
postid: null
},
methods: {
getComments () {
this.$http.get('/blog/' + this.postid+ '/comments').then((response) => {
this.comments = response.body.data;
});
},
createComment () {
this.$http.post('/blog/' + this.postid+ '/comments', {
body: this.body
}).then((response) => {
// console.log(this.body);
this.comments.unshift(response.body.data);
this.body = null;
});
}
},
mounted () {
this.getComments();
} }
</script>

Categories