Revamp your AngularJS controller for a fresh new look

How can a controller be refreshed in Angular? Take into account the scenario below:

<div ng-controller="MsgCtrl" ng-repeat="m in messages">{{m}}<br></div>
<script>
var ws = new WebSocket(something, something);
function MsgCtrl($scope) {
    $scope.messages = [];
    ws.onmessage = function(e) {
        $scope.$apply(function() {
            $scope.messages.push(e.data);
        });
    }
}
</script>

If the websocket connection fails, or needs to be restarted for any reason, a new websocket must be created and listened to. Is there a way to trigger the controller to run again, creating a new listener to push messages from the new connection into $scope?

In addition, as a follow-up question: Where is a reliable source to expand knowledge on Angular? The documentation on the official site may not provide clear guidance.

Answer №1

When there is a connection failure or the need to restart for any reason, it is important to reconnect the web socket. However, simply restarting the controller may not be the best approach.

Instead, I recommend creating a dedicated "web socket" service that can handle its own logic, such as reconnecting when needed. This way, the controller can focus on managing the model and view binding without getting bogged down with socket handling.

<html ng-app="MyApp">
....
<div ng-controller="MsgCtrl" ng-repeat="m in messages">{{m}}<br></div>
</html>
<script>

    var myApp = angular.module("MyApp",[]);
    myApp.factory("WebSocket",function(){
        var ws;
        var triedTime=0;
        var maxRetryTime=20;
        return {
            createWS: function(server,protocol,handler){
                ws = new WebSocket(server, protocol);
                ws.onmessage = handler;
                ws.onerror = function(e){
                    this.restartWS(server,protocol,handler);
                }
            },
            closeWS: function(){
                if(ws) ws.close();
            },
            restartWS: function(server,protocol,handler){
                if(triedTime<=maxRetryTime){
                    this.closeWS();
                    this.createWS(server,protocol);
                    triedTime++;
                }
            }
        };
    });

    function MsgCtrl($scope, WebSocket){
        $scope.messages = [];

        WebSocket.createWS("something","something",$scope.msgHandler);

        $scope.msgHandler = function(e){
            $scope.$apply(function() {
                //model update
                $scope.messages.push(e.data);

                var msg = JSON.parse(e.data);

                switch(msg.cmd)
                {
                    case "restart":
                    WebSocket.restartWS("something","something",$scope.msgHandler);
                    break;
                }
            });
        }

    }
</script>

In this scenario, the web socket will automatically attempt to reconnect upon receiving a "restart" message or encountering a connection issue. Hopefully, this solution proves useful for your needs.

Answer №2

  1. If you encounter issues, a simple solution is attempting to reload the page using $route.reload(). An even better approach is to reinitiate the websocket on the onerror.

  2. In my experience, the most beneficial platform for learning angularJS is Egghead. Additionally, stackoverflow serves as an excellent resource to seek clarification when needed.

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

Concerning the usage of i values within Javascript loops

As a newcomer to Javascript, I have a basic question. I am attempting to create a for loop where new variables are generated based on the value of i. How can I dynamically change variable names using the i value (without resorting to an array)? For insta ...

Creating a Jasmine test case to evaluate Angular functionality

I've recently started using Jasmine and I'm facing some challenges with mocking functions. Does anyone know how to mock global Angular functions like angular.forEach(), angular.isDefined(), and angular.isUndefined()? ...

Guide on using Ajax and spring MVC to dynamically fill a modal form

One JSP page displays database results in a table on the browser, allowing users to edit or delete each row. I want to implement a feature where clicking the edit link fetches specific customer data from the database using Spring MVC and Hibernate, display ...

Looking to display or conceal several divs according to the option selected from a dropdown menu?

I've been searching for a solution to my simple dropdown issue, but haven't had any luck in the forums. This is the code for the dropdown: <select id ="category_faq"> <option value="1">item1</option> <option value= ...

Unexpected behavior: Angular4/Javascript Date object alters when timezone is specified in Date constructor

In my Angular 4 application, I encountered an issue with a date retrieved from an API call. The date is in the format '1990-03-31T23:00:00-06:00' and when attempting to create a Date object and retrieve the month using getMonth(), it returns the ...

Tips for altering the appearance of a button:

Upon clicking the subscribe button and successfully subscribing, I want to display an unsubscribe option in my code. To achieve this, I have created two separate divs for each button, thinking that we could toggle between them. <div id ="subscribe_ever ...

The jQuery onClick function functions effectively for the initial two clicks; however, it ceases to

I am currently experimenting with jQuery to dynamically load a specific div from another page on my server into a designated section on the existing page. While the code is successfully functioning for the first two clicks on the website, it fails to work ...

What is the best way to merge two JSON objects linked by a foreign key in Angular?

Looking to display data from two JSON objects in a table, connected by a foreign key. The first set of JSON data is as follows: $scope.items = [ {status_id: 1, type: 1}, {status_id: 2, type: 2}, {status_id: 1, type: 3}, {status_id: 1, typ ...

Is there a way to convert an array into an object where the first value in the array becomes the name and the properties are an array of the remaining values within subarrays?

Looking to efficiently group elements of a multidimensional array with an unknown list, and transform it into an object while removing duplicate values in the first element of each subarray: For instance, here's the initial array: const arr = [[a, 1 ...

Ways to restrict the content div JSON display to only three items

Is it possible to limit the display of items from JSON in the content div to just three? The current code displays all downloaded items, but I want only 3 divs to be returned. <div id="p"></div> $.getJSON('element.json', function(d ...

What is the solution to the error message "Cannot assign to read only property 'exports' of object '#<Object>' when attempting to add an additional function to module.exports?"

I've been struggling for the past 5 days with this issue. Despite numerous Google searches, I haven't found a solution that works for me. I have a file called utils.js which contains useful functions to assist me. However, when I include the func ...

Tips for turning off hash-based redirection in AngularJS

Here is a specific URL: http://www.something.com/sometest/test/#registration Some code has been written based on #registration for Internet Explorer. However, when using AngularJS, it redirects to the following URL, which disrupts the logic: http://www ...

LESS — transforming data URIs with a painting mixin

Trying to create a custom mixin for underlining text, similar to a polyfill for CSS3 text-decoration properties (line, style, color) that are not yet supported by browsers. The idea is to draw the proper line on a canvas, convert it to a data-uri, and the ...

React infinite scroller - component fails to work when initial items are insufficiently loaded

In my Next.js app, I am dealing with a large firestore database containing many book objects. To filter these books based on keywords in their title, category, author, etc., I have implemented a searchbar. Due to the sheer volume of books, I am utilizing l ...

jquery accordion not functioning properly following partial ajax page refresh

Initially, I'm using a jQuery accordion that works perfectly. However, I encounter an issue when implementing some Ajax commands to reload part of the page, specifically the inner body section. After the page reloads, the accordion breaks because the ...

Can you explain how to use a toggle switch to make a select dropdown select a random option?

Currently, I am in the process of setting up a page for a character generator. Users will have the option to randomize traits or input their own. The interface includes toggle switches for the "choice vs random" options for each trait category, as well as ...

Why is Ajax/FormData rounding my decimal values?

When sending data from a form to my PHP script, I am utilizing the new FormData() method to retrieve the values. However, there are additional values that I append later on which are not part of the form: var fd = new FormData(document.getElementById(&apo ...

What sets apart elem['textContent'] from elem.textContent?

When dealing with a HTMLElement in JavaScript, is there any distinction between the following lines of code: elem['textContent'] = "Test"; versus elem.textContent = "Test"; This question arises when setting the text content of an HTMLElement. ...

"Vue.js integrates seamlessly with Tracking.js for advanced tracking

Has anyone successfully integrated the tracking.js library into a vueJS application? I followed these steps to install the package: npm install --save tracking After that, I defined the library in my main.js file like this: import tracking from 't ...

Effective Ways to Transfer Input Parameters to Karate File using npm

I am working on a test script that runs a series of queries. In order to execute the file, I need specific inputs such as URL and authorization header, which will vary depending on the environment. How can I prompt the user for these inputs in the command ...