Laravel Echo presence channel not working well with vue router
Asked Answered
F

1

1

The app is a chat app, using laravel and Vue, once a user logs in he sees the list of all online users, I called the Echo wrapper in the mounted component of the home page to show all online users, it works and shows them, the issue now is if I go to another page (via Vue Router) and then comeback to the home page it doesn't show the list of online users... Except manually i refresh the page again. Below is a snippet of my code:

mounted () {
// alert('Shoud work')
// console.log(Echo)
Echo.join('online')
.here((users) => {
  alert(JSON.stringify(users))
    this.users = users
})
.joining((user) => {
    this.users.push(user)
})
 .leaving((user) => {
    this.users = this.users.filter(u => (u.id !== user.id));
    })
  }
}
Fino answered 9/12, 2018 at 14:33 Comment(1)
Can you share the config you used to make the presence channel work? Laravel echo won't trigger .here() funcionCloset
B
2

Try leaving the channel using the component destroyed method. Since you never leaved the channel, once you come back, the issue could be that Echo.join won't load again, since the user is already on the channel, therefore, not triggering the .here which is the one responsible for loading your components users property with the chat users array.

mounted () {
    Echo.join('online')
    .here(users => {
        this.users = users
    })
    .joining(user => {
        this.users.push(user)
    })
    .leaving(user => {
        this.users = this.users.filter(u => (u.id !== user.id));
    })
},
destroyed() {
    Echo.leave(user => {
        this.users = this.users.filter(u => (u.id !== user.id));
    });
}

Or

mounted () {
    Echo.join('online')
    .here(users => {
        this.users = users
    })
    .joining(user => {
        this.users.push(user)
    })
    .leaving(user => {
        this.removeUser()
    })
},
destroyed() {
    Echo.leave(user => {
        this.removeUser()
    });
},
methods: {
    removeUser(user) {
        this.users = this.users.filter(u => (u.id !== user.id))
        // Any other reusable code...
    }
}

UPDATE:

If you intend to keep the user "logged in" through out your application, one way to do this is to create a "session" component. This component can or cannot have a template, however, it needs to stay loaded on every page. To access the the users list outside this session component, you could either store the users data into the browser's local store, use a global variable (ex. window.session.users), or, if available, use Vuex. Either way, as long as the users array is available for other components to use, the session component will keep that information up to date when users leave or join the application (or chat... or whatever join/leave rule you implement there).

For example, let's say you create a component named session. You could easily just place it inside your top navigation component template using <session></session>. Since the session component own template is empty, it won't affect the top navigation. However, it will be rendered, allowing you to manage the user's online state.

Bakehouse answered 11/12, 2018 at 2:50 Comment(1)
but if the user leaves, his prescence wont be seen in other parts of the application, can i use vuex to hold the list of all online users? what i'm currently doing is similar to the answer you suggested, I'm leaving the channel using Echo.leave('online')Fino

© 2022 - 2024 — McMap. All rights reserved.