Please be advised that the message is currently in the process of being typed

In my current setup, I am utilizing Laravel 5.6.7, Socket.IO, and vue.js while excluding Pusher and Redis. The following is the code snippet I am using to send messages directly to a user engaged in one-on-one chatting with me.

var url = "http://localhost:6001/apps/My_appId/events?auth_key=My_Key";

var socketId = Echo.socketId();
var request = {
    "channel": "private-Send-Message-Channel.2",
    "name": "MessengerEvent",
    "data": {
        "msg": message
    },
    "socket_id": socketId
};
axios.post(url, JSON.stringify(request)).then((response) => {
    //Message Sent
});

I am exploring ways to notify the user I'm chatting with that I am currently typing a message. Is it necessary to use the same code above, which triggers an XMLHttpRequest for each keystroke? Is this the only method available to convey to the user that typing is ongoing?

Update 1

Is there a more efficient approach instead of posting an XMLHttpRequest for every key press as mentioned earlier? In case the user types 200 characters, does that mean I'll have to trigger an XMLHttpRequest 200 times?

Alternatively,

Does Laravel offer events like whisper and listenForWhisper, similar to what's detailed here https://laravel.com/docs/5.6/broadcasting#client-events? My tech stack involves vue.js and laravel 5.6.7, and I'm not utilizing Pusher nor Redis.

Answer №1

When you check out the broadcasting documentation, you will find two code snippets that are useful for your Vue.js application.

To send client events, you can utilize Echo's whisper method:

Echo.private('chat')
    .whisper('typing', {
        name: this.user.name
    });

To receive client events, you can use the listenForWhisper method:

Echo.private('chat')
    .listenForWhisper('typing', (e) => {
        console.log(e.name);
    });

If you want to debounce the whisper method while the user is typing, you can refer to lodash documentation.

If you prefer not to rely on an additional library like lodash, you can implement debounce by wrapping whisper in a timeout. The following snippet will broadcast the whisper every 300ms:

isTyping() {
    let channel = Echo.private('chat');

    setTimeout(function() {
        channel.whisper('typing', {
            name: this.user.name,
            typing: true
        });
    }, 300);
}

The isTyping() function should be triggered when an onkeydown event occurs in the chat application's input field.

You also need to listen for the whisper once the app is created. This method will set the typing variable to true for 600ms after receiving the event.

created() {
    let _this = this;

    Echo.private('chat')
        .listenForWhisper('typing', (e) => {
            this.user = e.name;
            this.typing = e.typing;

            // remove is typing indicator after 0.6s
            setTimeout(function() {
                _this.typing = false
            }, 600);
        });
},

Answer №2

Although I am not an expert in Laravel, I have encountered this issue before.

Let's start by defining what "typing" means. Simply put, a user is considered to be typing if the input field for sending a message is not empty.

This definition is not foolproof as the user may walk away from the keyboard while in the middle of typing a message and never return to finish or send it. Nevertheless, it serves its purpose adequately.

Now, we no longer need to monitor each keystroke to determine if the user is actively typing. Essentially, determining if a user is typing now boils down to chat_input_box.length > 0 in code representation.

The focus should be on syncing this boolean value across users and servers instead of tracking individual key presses. To ensure real-time updates, we must capture input events on chat_input_box. If the boolean value changes during an event, socket.io can then transmit a signal indicating whether the user has initiated or ceased typing.

Upon receiving this signal, appropriate views can be toggled to provide visual cues to the user regarding the app's current state.

To address the scenario where a user begins typing but abruptly leaves, a timeout mechanism can be implemented. Once the timer expires, the "is typing" boolean value resets to false. However, each subsequent typing activity restarts the timer automatically.

Answer №3

Instead of sending an xhr request to your app, you have the option to directly broadcast events to chat users without involving your app.

The Laravel documentation explains:

There are times when you may want to send out an event to other connected clients without interacting with your Laravel application. This can be handy for things like notifying users of "typing" activity, where you need to inform users that someone is typing a message on a specific screen. To broadcast client events, utilize Echo's whisper method:

Echo.private('chat')
    .whisper('typing', {
        name: this.user.name
    });

To listen for client events, make use of the listenForWhisper method:

Echo.private('chat')
    .listenForWhisper('typing', (e) => {
        console.log(e.name);
    });

Answer №4

Correct, it is more efficient to use debouncing instead of emitting on every character change. By using the debounce method from the lodash library, you can wait for a short period before triggering the function.

I suggest checking out the documentation at: https://lodash.com/docs/4.17.5#debounce

Laravel's Echo is also a good option, especially if you don't need server involvement for the typing action. Emitting directly from client to client can be more efficient in this scenario.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ember.js: Storing function prototypes as objects

My interface consists of four vertical panels: The first panel displays the menu for selecting data The second panel allows you to choose a filter from a list The third panel shows the results based on the selected filter The fourth panel displays detail ...

resolved after a new promise returned nothing (console.log will output undefined)

Here is my Promise Function that iterates through each blob in Azure BlobStorage and reads each blob. The console.log(download) displays the values as JSON. However, when trying to close the new Promise function, I want the resolve function to return the ...

Tips on harnessing the power of AngularJS $scope

In need of assistance! I have a paragraph and a counter that I want to update whenever the user clicks on the paragraph, all using AngularJS. Below is the code snippet I've come up with: <!DOCTYPE html> <html> <head> <script src= ...

Learn the steps to retrieve a user's profile picture using the Microsoft Graph API and showcase it in a React application

I'm currently working on accessing the user's profile picture through Microsoft's Graph API. The code snippet below demonstrates how I am trying to obtain the profile image: export async function fetchProfilePhoto() { const accessToken = a ...

The Node/Express Rest API appears to keep directing requests to the same controller function, despite the mappings being correctly

Currently, I am in the process of developing a node/express REST API. When making requests to the following endpoints: http://localhost:5000/api/news and http://localhost:5000/api/news/?id=c5f69d56be40e3b56e55d80 I noticed that both URLs trigger the same ...

Create static HTML web pages using information from a text file

Exploring a new concept of a random joke generator that loads a unique html page with a quirky joke every time. Currently, the main index page is structured like this: <!DOCTYPE html> <html> <head><title>Jokes</title> ...

Activate the click event repeatedly in a loop

I am currently working on a bookmarklet to extract information from my Indiegala bundles that I have purchased. Instead of gifting the entire bundle, I prefer sending individual games one or two at a time as it is more convenient with the individual gift U ...

Which specific HTML element triggers the initiation of ajax in Jquery?

I have a situation where various HTML elements trigger ajax requests when clicked. My goal is to determine which specific element was clicked inside the ajaxComplete event. Although I attempted to use event.target, it only returns the entire document inst ...

What is the best way to transfer the http server variable between different layers in node.js without requiring it in a separate file?

I've developed a nodeJS application that involves creating a server in the file server.js. The code looks like this: http.createServer(app).listen(app.get('port'), function (err) { if (err) { console.error(err); } else { ...

What method is the most effective for extracting the first line of a file in Node.js quickly?

If you are faced with multiple lengthy text files and your goal is to extract data solely from the first line of each file (without delving into the rest), how would you recommend achieving this efficiently using Node.js? Appreciate any suggestions! ...

Conceal the Submit button upon completing the form submission using the load method

When creating a form and sending a request to another page, I use the following code: $(document).ready(function() { $("#send").click(function() { var text = $("#text").val(); var email = $("#email").val(); $("#exp").load("sendmail.php",{text: ...

PHP script failing to execute if/else statement during AJAX request

I am currently developing a website that heavily relies on Ajax, and I have chosen to use codeigniter for its construction. On the site, there is a form with the post method, and this form is submitted using an Ajax request that calls a function containi ...

What is the process of generating enum values using ES6 in Node.js?

Can JavaScript support enumerations with assigned integer values, similar to how other programming languages handle it? In C#, for instance, I can define an enum as follows: enum WeekDays { Monday = 0, Tuesday =1, Wednesday = 2, Thursday ...

Enhancing Efficiency and Optimization with jQuery

Recently delving into the world of jQuery, I have been on the lookout for ways to enhance the speed and performance of my code. If anyone has any tips or valuable resources that could aid me in this endeavor, I would greatly appreciate it. Thank you, Bev ...

Creating a custom table layout with JavaScript and jQuery

I've been grappling with a project for some time now, and I'm stuck on this particular issue. In my database, I have a table structured like this: ProjectName UserName SpentDays FirstProject User1 10 SecondProject User1 5 SecondProjec ...

Mastering advanced String templating using loops and control statements in Javascript

During runtime, I receive an array similar to the example below: var colors = ['red', 'green', 'blue']; I then need to create a JSON String that looks like this: { "color" : { "name" : "foo", "properties ...

``Why is my Vue.js ag-Grid filter component failing to function?

I have recently started working with vue-js and ag-grid, and I wanted to implement a custom filter on my ag-grid. I attempted to use a component as a filter based on the example provided in the vue-js ag-grid documentation: "https://www.ag-grid.com/javascr ...

In JavaScript, the code is designed to recognize and return one specific file type for a group of files that have similar formats (such as 'mp4' or 'm4v' being recognized as 'MOV')

I am working on a populateTable function where I want to merge different file types read from a JSON file into one display type. Specifically, I am trying to combine mp4 and m4v files into MOV format. However, despite not encountering any errors in my code ...

The Chevron icon is not pointing downwards even though it has already gone upwards

I want to toggle a chevron icon, but nothing seems to be happening. $("span:last").removeClass("glyphicon-chevron-down").addClass("glyphicon-chevron-up"); When I add this code below the slideToggle function without an if-else section, the icon changes to ...

Determine if a mobile application has been installed using Vue.js

I am currently developing a web application and have implemented a check to determine whether the user is accessing it from a mobile device or laptop. Let's consider the link as: my-site.com In addition to the web version, my site also offers a mobi ...