List down an array of messages from the converstions - vue.js

I would like to list down the messages from a chat Id ... I am using Vue js and i could get the data but i am not able to display them using the component . anyone would like to guide ?
This is my message component where the messages will be displayed here
<template>
<div class="row w-20 " >
<div class="card col-4 ">
<ul>
<li v-for="(conversation,index) in conversation" :key="conversation.id">
<div >
{{message}}
</div>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
props: ['conversation_index_route'],
data() {
return {
conversations: [],
url: 'http://127.0.0.1:8000/comms/conversation/'
}
},
beforeMount() {
this.$eventBus.$on('selectConversation', this.getConversations)
this.getConversations();
},
methods: {
getConversations(id) {
console.log(this.url+id);
axios.get(this.url+ id)
.then(response => {
this.conversations = response.data;
})
}
}
}
</script>
This are the data that can seen in VUE .. I need to display the messages which is in array
conversation_index_route:"http://127.0.0.1:8000/comms/conversation"
conversations:Object
all_staff_attended:false
centre_id:5
children:"3828,4197,7748,11591,12376,12394,12433,12441,12754,12755,12765,13284,14149,14602,14656,14941"
classes:"139"
cover_image:"https://via.placeholder.com/150x150"
created_at:"2020-06-09 19:14:20"
exited_users:null
id:258
last_id:1917
messages:Array[5]
0:"{"_id":1921,"text":"Okayyyy","createdAt":"2020-06-10 01:46:10","user":{"_id":13077,"name":"Mom (Alex,Jacob,Ahmad,Patrick,Ethan Lim)","avatar":null},"image":null,"video":null,"file":null,"images":{},"public_id":null,"read":{"0":13077,"1":14083,"2":3}}"
1:"{"_id":1920,"text":"Chvfhdgy","createdAt":"2020-06-10 01:46:00","user":{"_id":13077,"name":"Mom (Alex,Jacob,Ahmad,Patrick,Ethan Lim)","avatar":null},"image":null,"video":null,"file":null,"images":{},"public_id":null,"read":{"0":13077,"1":14083,"2":3}}"
2:"{"_id":1919,"text":"Heyyyy","createdAt":"2020-06-10 01:45:28","user":{"_id":14083,"name":"Siti","avatar":"https:\/\/api.cloudinary.com\/v1_1\/ds13udsoy\/image\/download?timestamp=1592882587&public_id=archaana%2Flibrary%2Fprofile%2Fstaff%2Fcd3ecc89-f67e-4e5e-89e9-badafd903bba_1591032813&type=private&expires_at=1592882647&signature=d0f12d520d18ff1a6b594bcb0ecb742f8ffd88a6&api_key=567141618229528"},"image":null,"video":null,"file":null,"images":{},"public_id":null,"read":{"0":14083,"1":13077,"2":3}}"
3:"{"_id":1918,"text":"Hello","createdAt":"2020-06-10 01:45:14","user":{"_id":14083,"name":"Siti","avatar":"https:\/\/api.cloudinary.com\/v1_1\/ds13udsoy\/image\/download?timestamp=1592882587&public_id=archaana%2Flibrary%2Fprofile%2Fstaff%2Fcd3ecc89-f67e-4e5e-89e9-badafd903bba_1591032813&type=private&expires_at=1592882647&signature=d0f12d520d18ff1a6b594bcb0ecb742f8ffd88a6&api_key=567141618229528"},"image":null,"video":null,"file":null,"images":{},"public_id":null,"read":{"0":14083,"1":13077,"2":3}}"
4:"{"_id":1917,"text":"Hahaha","createdAt":"2020-06-10 01:14:34","user":{"_id":13077,"name":"Mom (Alex,Jacob,Ahmad,Patrick,Ethan Lim)","avatar":null},"image":null,"video":null,"file":null,"images":{},"public_id":null,"read":{"0":13077,"1":181,"2":14083,"3":3}}"
parent_users:"2413,3461,11690,11770,11786,12262,12263,13077,14232,15275,16713"
parents:Array[11]
staff_users:"321,16707,12117,13488,14083"
staffs:Array[5]
status_id:1
title:"Class 0906"
updated_at:"2020-06-09 19:14:20"
url:"http://127.0.0.1:8000/comms/conversation/"
Can Anyone help me how to display the array of message in the component ..

Alright let's assume that this is how your response is structured:
{
all_staff_attended: false,
centre_id: 5,
messages: Array[5]
...etc.
}
Then when you call your getConversations method you could make your data property this.conversations equal to messages array from your response:
getConversations(id) {
console.log(this.url+id);
axios.get(this.url+ id)
.then(response => {
//from your response you would want to get messages array
this.conversations = response.data.messages;
})
}
Once you got your messages array, you can then loop through it with v-for like so:
<ul>
<li v-for="(conversation,index) in conversation" :key="conversation.id">
<div>
<p>Message: {{conversation.text}}</p>
<p>User: {{conversation.user.name}}</p>
<p>Created at: {{conversation.createdAt}}</p>
</div>
</li>
</ul>
Now, you can access each object of the messages array like in the example above.

Related

make the title post clickable vue

I'm using vue + laravel and i try do display the data from api like this:
<div v-for="article in articles" :key="article.id" class="hieght">
<div class="NewArticle">
<h6 class="NewArticleTitle">{{ article.title.ar }}</h6>
</div>
<div>
<p class="NewArticleBody">{{ article.excerpt.ar }}</p>
</div>
</div>
and the script is:
<script>
export default {
data() {
return {
articles: []
}
},
created() {
this.axios
.get('http://localhost:8000/api/articles/')
.then(response => {
this.articles = response.data;
});
}
}
But I want the post to open when I click on the title, I don't know how can i do that using vue
You need to create a view component for your post. and make the h6 title tag a router-link tag that takes you to the post (or article) details page.

infinite loop when create infinite scroll using vue.js and laravel

good day; kindly need your support to finalize this issue i try to make infinite scrolle using laravel and vue.js and my proplem is get in finite loop to set request to data base and mu applocation hang up this is my code x component
<template>
<div class="container" style="margin-top:50px;">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header"><strong> Laravel Vue JS Infinite Scroll - ItSolutionStuff.com</strong></div>
<div class="card-body">
<div>
<p v-for="item in list">
<a v-bind:href="'https://itsolutionstuff.com/post/'+item.slug" target="_blank">{{item.title}}</a>
</p>
<infinite-loading #distance="1" #infinite="infiniteHandler"></infinite-loading>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
mounted() {
alert()
console.log('Component mounted.')
},
data() {
return {
list: [],
page: 1,
};
},
methods: {
infiniteHandler($state) {
let vm = this;
this.$http.get('/Services?page='+this.page)
.then(response => {
return response.json();
}).then(data => {
$.each(data.data, function(key, value) {
vm.list.push(value);
});
$state.loaded();
});
this.page = this.page + 1;
},
},
}
</script>
this is my route
Route::get('/Services', 'ServicesController#Services');
Problem 1
You are binding to the distance property wrong.
Solution
Instead of <infinite-loading #distance="1" #infinite="infiniteHandler"></infinite-loading>
it should be
<infinite-loading :distance="1" #infinite="infiniteHandler"></infinite-loading>
Problem 2
In the code, this.page is being incremented before $http.get is resolved.
This may result in unintentional side effects.
Solution
As per the example in docs vue-infinite-loading hacker news example you should be incrementing the page after data is loaded.

Why does axios delete not work as I want, how to fix it?

I took the data from https://jsonplaceholder.typicode.com/posts, I got it out normally, but I also want to create a button when I click on it, the post will be deleted. I wrote the code, but it does not work, can you tell me what is the error? When you click on the button in the console writes 'delete', but the post remains.
Screenshot of console
<template>
<div id="app">
<ul>
<li v-for="post of posts">
<p>{{ post.title }}</p>
<p>{{ post.body }}</p>
<button #click="deleteData(post._id)">Delete</button>
</li>
</ul>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'app',
data () {
return{
posts: [],
}
},
created(){
axios.get('http://jsonplaceholder.typicode.com/posts').then(response => {
this.posts = response.data
})
},
methods: {
deleteData(_id) {
axios.delete('http://jsonplaceholder.typicode.com/posts/' + id)
.then(response => {
console.log('delete')
this.posts.splice(
this.posts.findIndex(e => e.id === id)
)
})
.catch(function(error) {
console.log(error)
})
},
}
}
</script>
Your approach is good, but you're using methods in wrong way.
There are two things you have to remember.
First, your post variable is an array.
API gives you json data, and what you have to do is to push that data into your array, instead of using = operand
Secondly, splice(index) just returns the same object.
Using splice(index, 1) instead.
It will delete 1 post from that index.

Axios setting response data in vue component variable but variable not displaying data on browser

Axios setting response data in Vue component variable but variable not displaying data on the browser. We can see data on console but when I display, Browser shows me nothing. Data are in JSON Format.
Snapshot:
Output:
<template>
<div class="card">
<div class="card-header">Subject</div>
<div class="card-body" >
<!-- <ul class="list-group">
<li class="list-group-item" :key = "message.id" v-for = "message in messages"> {{ message.subject}}</li>
</ul> -->
{{messages}}
</div>
</div>
</template>
<script>
export default{
name: 'subject-component',
data () {
return {
messages:{}
}
},
mounted () {
},
created(){
axios.get('http://127.0.0.1:8000/subject/get')
.then(response => {this.messages = response.data})
.catch((error) => console.log(error));
}
}
</script>
By setting up the project again, this issue has been resolved. And again I used the same approach for axios request like.
axios.get('http://127.0.0.1:8000/get/subjects')
.then((response)=>(this.subjects = response.data))
.catch(function(error){console.log(error)});
Thank you all for your effort.

Send data from one component to another in vue

Hi I'm trying to send data from one component to another but not sure how to approach it.
I've got one component that loops through an array of items and displays them. Then I have another component that contains a form/input and this should submit the data to the array in the other component.
I'm not sure on what I should be doing to send the date to the other component any help would be great.
Component to loop through items
<template>
<div class="container-flex">
<div class="entries">
<div class="entries__header">
<div class="entries__header__title">
<p>Name</p>
</div>
</div>
<div class="entries__content">
<ul class="entries__content__list">
<li v-for="entry in entries">
{{ entry.name }}
</li>
</ul>
</div>
<add-entry />
</div>
</div>
</template>
<script>
import addEntry from '#/components/add-entry.vue'
export default {
name: 'entry-list',
components: {
addEntry
},
data: function() {
return {
entries: [
{
name: 'Paul'
},
{
name: 'Barry'
},
{
name: 'Craig'
},
{
name: 'Zoe'
}
]
}
}
}
</script>
Component for adding / sending data
<template>
<div
class="entry-add"
v-bind:class="{ 'entry-add--open': addEntryIsOpen }">
<input
type="text"
name="addEntry"
#keyup.enter="addEntries"
v-model="newEntries">
</input>
<button #click="addEntries">Add Entries</button>
<div
class="entry-add__btn"
v-on:click="openAddEntry">
<span>+</span>
</div>
</div>
</template>
<script>
export default {
name: 'add-entry',
data: function() {
return {
addEntryIsOpen: false,
newEntries: ''
}
},
methods: {
addEntries: function() {
this.entries.push(this.newEntries);
this.newEntries = '';
},
openAddEntry() {
this.addEntryIsOpen = !this.addEntryIsOpen;
}
}
}
</script>
Sync the property between the 2:
<add-entry :entries.sync="entries"/>
Add it as a prop to the add-entry component:
props: ['entries']
Then do a shallow merge of the 2 and emit it back to the parent:
this.$emit('entries:update', [].concat(this.entries, this.newEntries))
(This was a comment but became to big :D)
Is there a way to pass in the key of name? The entry gets added but doesn't display because im looping and outputting {{ entry.name }}
That's happening probably because when you pass "complex objects" through parameters, the embed objects/collections are being seen as observable objects, even if you sync the properties, when the component is mounted, only loads first level data, in your case, the objects inside the array, this is performance friendly but sometimes a bit annoying, you have two options, the first one is to declare a computed property which returns the property passed from the parent controller, or secondly (dirty and ugly but works) is to JSON.stringify the collection passed and then JSON.parse to convert it back to an object without the observable properties.
Hope this helps you in any way.
Cheers.
So with help from #Ohgodwhy I managed to get it working. I'm not sure if it's the right way but it does seem to work without errors. Please add a better solution if there is one and I'll mark that as the answer.
I follow what Ohmygod said but the this.$emit('entries:update', [].concat(this.entries, this.newEntries)) didn't work. Well I never even need to add it.
This is my add-entry.vue component
<template>
<div
class="add-entry"
v-bind:class="{ 'add-entry--open': addEntryIsOpen }">
<input
class="add-entry__input"
type="text"
name="addEntry"
placeholder="Add Entry"
#keyup.enter="addEntries"
v-model="newEntries"
/>
<button
class="add-entry__btn"
#click="addEntries">Add</button>
</div>
</template>
<script>
export default {
name: 'add-entry',
props: ['entries'],
data: function() {
return {
addEntryIsOpen: false,
newEntries: ''
}
},
methods: {
addEntries: function() {
this.entries.push({name:this.newEntries});
this.newEntries = '';
}
}
}
</script>
And my list-entries.vue component
<template>
<div class="container-flex">
<div class="wrapper">
<div class="entries">
<div class="entries__header">
<div class="entries__header__title">
<p>Competition Entries</p>
</div>
<div class="entries__header__search">
<input
type="text"
name="Search"
class="input input--search"
placeholder="Search..."
v-model="search">
</div>
</div>
<div class="entries__content">
<ul class="entries__content__list">
<li v-for="entry in filteredEntries">
{{ entry.name }}
</li>
</ul>
</div>
<add-entry :entries.sync="entries"/>
</div>
</div>
</div>
</template>
<script>
import addEntry from '#/components/add-entry.vue'
import pickWinner from '#/components/pick-winner.vue'
export default {
name: 'entry-list',
components: {
addEntry,
pickWinner
},
data: function() {
return {
search: '',
entries: [
{
name: 'Geoff'
},
{
name: 'Stu'
},
{
name: 'Craig'
},
{
name: 'Mark'
},
{
name: 'Zoe'
}
]
}
},
computed: {
filteredEntries() {
if(this.search === '') return this.entries
return this.entries.filter(entry => {
return entry.name.toLowerCase().includes(this.search.toLowerCase())
})
}
}
}
</script>