Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

theUnforgiven's avatar

problem with v-model on message input & isTyping indicator

Hi all,

I have a problem with a v-model on “message” input and isTyping. As the code is quite long I made a gist - https://gist.github.com/lstables/1ffdbe4e2d1c19015862b9398f7024e6

As you can see below. the message is empty and even when I was typing the isTyping is still set to false.

I’m guessing this is because it should be within the groups array, so question is how does one get this working so the typing indicator and message inputs works, as this should be realtime using Pusher, which Pusher is receiving the typing indicator and message, but Vue isn’t doing as it should, obviously my mistake, so hoping you wonderful lot will help me out here :slight_smile:

0 likes
31 replies
mikebonds's avatar

It doesn't look like you are actually setting typing to true in the isTyping method. You are sending true, but not actually updating the vue data. As for message being empty, I can't tell why that isn't updating. I am sure there is something that I just can't see due to the amount of code in the gist. If I see what the issue is, I will reply again.

mikebonds's avatar

What is the value of this.message when you post in the store() method?

mikebonds's avatar

Sorry, one more quick reply. If you have vue dev tools open on that component before you start typing, vue dev tools might not be updating.

theUnforgiven's avatar

Figured i quickly show that dev tools is open and I can confirm is working and refreshed, but have a look at this screen cast - https://www.dropbox.com/s/ng158s8oxny3s2r/chat.mov?dl=0

Hitting the button for the store method seems to do nothing, but if I check Pusher and the database I can see the typing indicator works and also the message was sent to Pusher and also the db.

mikebonds's avatar

Just noticed you are using parenthesis when calling the store method when you call it from the input and the submit click. Remove the parenthesis. You don't need to be passing group_id to store as it is already using this.group_id.

Also, trying entering text in the input then opening up vue dev tools to see the updated data.

theUnforgiven's avatar

Yes, I was tinkering around before posting here, but removed both () from both the input and button

theUnforgiven's avatar

Typing in the input something then opening up dev tools it does then show message:"something" And the isTyping still not working.

mikebonds's avatar

you have @keydown="isTyping" which is calling your isTyping method. In that method you will need to set this.typing = true as that is the property in your data. You are currently not setting that anywhere.

1 like
theUnforgiven's avatar

Ok, added that, but still nothing, also I have in the store method

store() {
                axios.post('/conversations', {message: this.message, group_id: this.group.id})
                .then((response) => {
                    
                    this.conversations.push(response.data);
                    this.message = ''; // To empty the message out, but this isn't working either, and doesn't seem to be posting to the server, but checking the network tab I see it is and is 200 response.
                });
            },
theUnforgiven's avatar

isTyping method also is set oto true:

isTyping() {
                let channel = Echo.private('groups.' + this.group.id);
                
                setTimeout(function() {
                    channel.whisper('typing', {
                        user: Laravel.userName,
                        typing: true // true here
                    });
                }, 3500);
            },

mikebonds's avatar

That isn't setting typing to true in the component you need to explicitly do this.typing = true, what you have is only sending payload to a listener you have setup. Have you removed the parenthesis from the calls to your store method?

theUnforgiven's avatar
isTyping() {
                let channel = Echo.private('groups.' + this.group.id);
                this.typing = true // set to true here
                setTimeout(function() {
                    channel.whisper('typing', {
                        user: Laravel.userName,
                        typing: true
                    });
                }, 3500);

                
            },

And nothing and yes removed ()

<input
                                        type="text" 
                                        class="form-control input-sm chat-input" 
                                        placeholder="Type your message here..." 
                                        v-model="message" 
                                        @keyup.enter="store" 
                                        @keydown="isTyping" 
                                    >
                                    <span class="input-group-btn">
                                        <button class="btn btn-success" 
                                                style="border-radius: 0px 10px 10px 0px!important;" 
                                                @click.prevent="store"
                                        >
                                        <i class="far fa-paper-plane"></i> Send
                                        </button>
                                    </span>
mikebonds's avatar

looks good. You are still not seeing what you expect?

theUnforgiven's avatar

Nope and the message isn't been pushed into the list and the input isn't been emptied after submitting either, really weird this.

mikebonds's avatar

Alright. Well I'll try to take another look with your later. There is a lot going on, and a few more things that probably need dissecting.

theUnforgiven's avatar

Pusher is showing typing indicator and the message, but the chat isn't updating in realtime, i did forgot to run queue:listen, but that's made no difference :)

theUnforgiven's avatar

I'm still having issues with the typing indicator and the message not clearing and updating in realtime, even though as you can see from the last image I posted, Pusher is been notified so this obviously as something to do with the Vue file, but I'm unsure as to what.

theUnforgiven's avatar

It seems that after playing around again for a couple of hours, it's something to do with Authorization on the channels.php class.

Or maybe something else, i've missed not sure!!!

But The conversation list shows now, typing indicator still doesn't and the input doesn't clear either, but again think this is linked to the same problem.

I've just tried again to got the following error

[Vue warn]: Error in render: "TypeError: Cannot read property 'account_type' of undefined"

found in

---> <GroupChat> at resources/assets/js/laravel/components/GroupChat.vue
       <Groups> at resources/assets/js/laravel/components/Groups.vue
         <Root>

Which relates to this piece of code:

<div class="panel-body chat-panel">
                                <ul class="list-unstyled">
                                    <li class="media" v-for="(conversation,index) in conversations" :key="index">
                                        <i class="far fa-user mr-3 img-thumbnail"></i>
                                        <div class="media-body">
                                            <h5 class="mt-0 mb-1">{{ user }} ({{ conversation.user.account_type | capitalize }})</h5>
                                            <p>
                                                {{ conversation.message }}<br />
                                                <small class="text-muted pt-1">{{ conversation.created_at | formatDate }}</small>
                                            </p>
                                        </div>
                                    </li>
                                </ul>
                                <span v-show="typing" class="help-block" style="font-style: italic;">
                                    {{ user.name }} is typing...
                                </span>
                            </div>

Which comes from the GET response which does have all the user details in etc, so not sure why it's not rendering.

Which you can see from the response in the network tab:

created_at: "2019-06-13 12:16:57"
group_id: 127
id: 363
message: "skjdhff"
updated_at: "2019-06-13 12:16:57"
user: {id: 126, membership_number: "SBM02101925", title: null, name: "Del Trotter", ema...
YeZawHein's avatar

@theunforgiven I don't know the whole structure of your code.But I think your conversations should object in my mind.Something like this

 data() {
     return {
        conversations: {
        message: []
        },  
                message: '',
            }
        },
theUnforgiven's avatar

My data obj is:

data() {
            return {
                group_id: this.group.id,
                conversations: [],
                typing: false,
                user: '',
                message: '',
                groups: []
            }
        },
theUnforgiven's avatar

No, I don't think that will work, as I push the response into this array also.

YeZawHein's avatar

@theunforgiven you can do this

store(){
            if (this.message.length != 0) {
                this.conversions.message.push(this.message);
                axios.post('/conversations', {
                    message : this.message,
                    conversations:this.conversations
                })
                .then(response => {
                    console.log(response);
                    this.message = ''
                })
                .catch(error => {
                    console.log(error);
                });
            }
        }

theUnforgiven's avatar

That just shows Cannot read property 'message' of undefined

YeZawHein's avatar

i think this error will be in v-for

 <li class="media" v-for="(value, index) in conversations.message" :key="index">
  {{value}}
</li>
theUnforgiven's avatar

No that doesn't work either and i don't particularly want to go down that road, what I have setup already does work 90%

YeZawHein's avatar

I believe that one conversation will have many messages.So I suggest that way.Never mind :)

Next

Please or to participate in this conversation.