3

I am trying to make a realtime chat in Laravel using Vue and Pusher. I already have done everything but I can´t understand why my component ChatMessages.vue can show {{ message.user }} where I can see that the user has a name but it can´t show {{ message.user.name }}.

Example:

{{ message.user }}

Here are the results

Here are the results

{{ message.user.name }}

Here are the results

Here are the results

This is my code:

ChatMessages.vue

<template>
<ul class="chat">
    <li class="left clearfix" v-for="message in messages">
        <div class="chat-body clearfix">
            <div class="header">
                <strong class="primary-font">
                    {{ message.user.email }}
                </strong>
            </div>
            <p>
                {{ message.message }}
            </p>
        </div>
    </li>
</ul>
</template>

<script>
  export default {
    props: ['messages'],

    mounted(){
        console.log(this.messages)
    }
  };
</script>

ChatForm.vue

<template>
<div class="input-group">
    <input id="btn-input" type="text" name="message" class="form-control input-sm" placeholder="Type your message here..." v-model="message.message" @keyup.enter="sendMessage">

    <span class="input-group-btn">
        <button class="btn btn-primary btn-sm" id="btn-chat" @click="sendMessage">
            Send
        </button>
    </span>
</div>
</template>

<script>
export default {
    props: ['user'],

    data() {
        return {
            message:{
                message: ' ',
                user: this.user
            }
        }
    },

    methods: {
        sendMessage() {
            this.$emit('messagesent', this.message)

            this.message = {}
        }
    }    
}
</script>

App.js

Vue.component('chat-messages', 
require('./components/ChatMessages.vue').default);
Vue.component('chat-form', require('./components/ChatForm.vue').default);

const app = new Vue({
el: '#app',

data: {
    messages: []
},

mounted() {
    this.fetchMessages();
    Echo.private('chat')
    .listen('MessageSent', (e) => {
        this.messages.push({
            message: e.message.message,
            user: e.user
        });
    });
},

methods: {
    fetchMessages() {
        axios.get('/chat/messages').then(response => {
            this.messages = response.data;
        })
    },

    addMessage(message) {
        this.messages.push(message);

        axios.post('/chat/messages', message).then(response => {
            //console.log(response.data);
        })
    }
}
});

The view

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">

<title>HelpEachOthers</title>

<!-- Bulma CDN -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.css" />

<!-- Bootstrap CDN -->
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
</head>
<body>
<div class="container" id="app">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">Chats</div>

                <div class="panel-body">
                    <chat-messages :messages="messages"></chat-messages>
                </div>
                <div class="panel-footer">
                    <chat-form v-on:messagesent="addMessage" user="{{ Auth::user() }}"></chat-form>
                </div>
            </div>
        </div>
    </div>
</div>

<script src="{{ URL::asset('js/app.js') }}"></script>
</body>
</html>

This is only happening in new messages that are sent after the page has loaded. The messages that were in the database when the component is mounted are displayed with the correct name tag. For test this I have 2 chrome windows with 2 differentes users. In the windows where I am sending the message I can´t see the name but in the other window with other user I can see the name in realtime, without reloading.

2
  • What does Auth::user() return? If it's some sort of JSON object, shouldn't you be binding the user prop attribute, ie v-bind:user="{{ Auth::user() }}"? Commented Jan 2, 2019 at 1:17
  • If I understood you, if I have a conversation between a few users all messages will have the name of the authenticated user in his session instead of having the name of the autor of the message. Am I right? Commented Jan 2, 2019 at 1:22

2 Answers 2

3

You appear to be passing the user prop as a JSON string. For example, if you were to view your page source, you would see something like...

<chat-form ... user="&quot;id&quot;:1,&quot;name&quot;:&quot;Test&quot;,..."

In order to make it an object with properties you can access (like .name, .email, etc), you need to bind the attribute value, eg

<chat-form v-on:messagesent="addMessage" 
           v-bind:user="{{ Auth::user() }}">
</chat-form>

You can also use the v-bind shorthand syntax, eg

:user="{{ Auth::user() }}"

See https://v2.vuejs.org/v2/guide/components-props.html#Passing-Static-or-Dynamic-Props

Sign up to request clarification or add additional context in comments.

1 Comment

Thats it, sorry for the late reply. Thank you so much.
0

Not entirely sure if this is the answer but my first troubleshooting suggestion would be to check the e.user type value (e.g String or Object) inside of App.js (mounted method).

Hard to say without spinning up a local env but I’m thinking that value is a JSON string, not a JS object.

If the value is of data type string, you can probably convert it to an object using JSON.parse(e.user)

Good luck!

9 Comments

Same issue. Thanks anyway
Interesting. What’s the output of the below look like? console.log(e, typeof e.user)
{message: {…}, user: {…}} "object"
And just for sanity sake, console.log(e.user.name)?
I think we’ve found it. Inside of sendMessage (ChatfForm) you’re resetting this this.message object to {}. Instead it should be set to { message:’’, user: this.user }
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.