How can the Angular.js Service Factory module be configured to yield the inner code as a function?

I am completely new to working with angular.js. Recently, I wrote my first Service which takes a JSON object and updates the scope of the controller. However, I find myself a bit confused about some aspects of it. Specifically, I am unsure if I should wrap the inner code of sseListener and return it as a function, and why this is necessary.

Furthermore, I am concerned that if I inject this service into multiple controllers, it might result in duplicate event listeners. Ideally, I only want to have one event listener active at all times.

one@demo ~/cloudimageshare-monitoring/project/app/scripts $ cat services/sse_listen.js 
angular.module('monitorApp')
.factory('sseListener', function () {
    var source = new EventSource('/subscribe');

    source.addEventListener('message', function(e) {
        var result = JSON.parse(e.data);
         event = Object.keys(result)[0];
         switch(event) {
             case "cpuResult":
                 cpuUpdate(result);
             break;
         }
    });
}

one@demo ~/cloudimageshare-monitoring/project/app/scripts $ cat controllers/main.js 
'use strict';

angular.module('monitorApp')
.controller('homeCtrl', function($scope, $location, $document) {
    console.log("s");
});

angular.module('monitorApp')
.controller('cpuCtrl', function($scope) {
    $scope.apiTimeStamp = "";
    $scope.infoReceived = "";
    $scope.last15 = "";
    $scope.last5 = "";
    $scope.lastMinute = "";

    var cpuUpdate = function (result) {
        $scope.$apply(function () {
            $scope.apiTimeStamp = result.cpuResult.timestamp;
            $scope.infoReceived = new Date();
            $scope.last15 = result.cpuResult.metrics['1m'].data
            $scope.last5 = result.cpuResult.metrics['5m'].data
            $scope.lastMinute = result.cpuResult.metrics['15'].data
        });
    }

});

Answer №1

If you're wondering how your factory can access the cpuUpdate function without directly calling it, a solution would be to utilize $rootScope.$broadcast(eventName, data) and handle the event in your controller. It's recommended to return an object from factories, but since there's no need for injection, it's best to include it in an app.run block. Below is a revised version of your code incorporating these changes:

angular.module('monitorApp').
    run(function ($rootScope) { //Inject the $rootScope
        var source = new EventSource('/subscribe');

        source.addEventListener('message', function(e) {
            var result = JSON.parse(e.data);
             event = Object.keys(result)[0];
             switch(event) {
                 case "cpuResult":
                     // Broadcast the event with data
                     $rootScope.$broadcast('$cpuResult', result);
                 break;
             }
        });
    }).
    controller('cpuCtrl', function($scope)){
        $scope.apiTimeStamp = "";
        $scope.infoReceived = "";
        $scope.last15 = "";
        $scope.last5 = "";
        $scope.lastMinute = "";

        // Pass the event to cpuUpdate,
        var cpuUpdate = function (e, result) { 
            $scope.$apply(function(){
                $scope.apiTimeStamp = result.cpuResult.timestamp;
                $scope.infoReceived = new Date();
                $scope.last15 = result.cpuResult.metrics['1m'].data
                $scope.last5 = result.cpuResult.metrics['5m'].data
                $scope.lastMinute = result.cpuResult.metrics['15'].data
            });
        };

        //Listen for the event, call cpuUpdate when caught
        $scope.$on('$cpuResult', cpuUpdate);
    });

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

Add and condense sub-row

I am struggling to make the child row collapse and append when clicking on the parent row. It seems like my code is not working properly. Can anyone offer some guidance or assistance? This is the code for the parent row: $j(document).ready(function(){ $ ...

Using Angular, we can assign an array iteration as the value for a dropdown option in

Following the controller logic: $scope.form_data = { day: 'Day' }; $scope.days = [ 'Day',1,2,3,4,5,6,7,8,9,10, 11,12,13,14,15,16,17,18,19,20, 21,22,23,24,25,26,27,28,29,30, 31 ]; In the html section: <select n ...

Explore a unique item by utilizing AngularJS, Morphia, MongoDB, and Java

Currently, I am in the process of learning how to query a single object within a collection. Essentially, I have a set of records, and upon clicking on a specific record, I need to invoke a rest service using the unique id associated with the clicked row. ...

Using AngularJS to incorporate the render directive in an HTML string

My goal is to render a directive and have it displayed correctly in HTML using AngularJS. I have implemented a service that handles displaying warning messages to users. I am able to call this service per controller and specify the message to be shown. One ...

Customizing table headers in Yajra Laravel Datatables

I am encountering an issue with category sorting on my list of products. When I click on category sorting, it only shows the same category and product name repeatedly. All other sorting functions are working correctly, except for category sorting. I have ...

ReactJs: Struggling to programmatically set focus on an element with React.createRef()

Looking to detect when a user clicks on an arrow using the keyboard? I stumbled upon the Arrow Keys React react module. To make it work, you need to call the focus method on a specific element. Manually clicking on an element does the trick: https://i.s ...

Obtain the "unprocessed" data from an incorrect input field

In my form, I have an input field with validations that work perfectly. Here is the basic structure of the input field: <input class="form-control" type="number" ng-model="zipcode" ng-minlength="5" ng-maxlength="5" id="zipcode" name="zip ...

What's preventing me from invoking this object's function through an inline anchor?

CSS: <div class="box"> <p>This is a box</p> </div> Javascript: var box = { content : (function() {return ("This is the content of the box")}) }; alert("Box content: \n" + box.content()); $("output").text( +"<br/ ...

Using Vue to dynamically upload multiple files simultaneously

Although this question has been asked frequently, most of the answers do not address a key issue - how to upload multiple images while knowing which image belongs to which data. Attempting to bind v-model to input file doesn't work as expected, and ev ...

Tables with customizable forms for multiple entries

I have integrated the editable plugin found on this website to enable in-place editing functionality. The code snippet I am utilizing is sourced from their documentation page, which is intended for adding new records. However, my requirement is to use it ...

Displaying selected list item while concealing the original

I have a dropdown menu with several options. What I am looking for is to have it so that when we click on the drop down, a list of choices appears. Then, when we select an option from the dropdown, the original selection should be replaced with the one th ...

Encountering a JavaScript error in the backend of Joomla 3.2

I am facing an issue with buttons on my Joomla 3.2.3 sites in the backend. The save, edit (material, module, menu...) buttons are not working properly. These sites were deployed using Akeeba Kickstart. Interestingly, everything worked fine on the developme ...

Transform JSON query conditions into MongoDB/Mongoose commands

I'm currently developing an application using Angular 8 on the front end and NodeJS 12 with MongoDB 4 / Mongoose 5 on the back end. Using the Angular query builder module, I have generated a query in JSON format. This JSON object will be sent to the ...

JavaScript Toggle Visibility on Click

Click to reveal a new div <div id="box1">abc</div> <div id="box2" style="display:none;">awklnnbc</div> <div id="box3" style="display:none;">wgweilwe</div> <div id="box4" style="display:non ...

Why does the error message "$(…).functionName() is not a function" occur and what steps can be taken to prevent it from

I have encountered a console error message: $(...).functionName() is not a function Here is my function call: $("button").functionName(); This is the actual function: $.fn.functionName = function() { //Do Something }(jQuery); What ca ...

Vue.js quasar q-input component not triggering event upon input modification

I have a scenario with two components - ModalName.vue as the child component and AddTask.vue as the parent component. In ModalName.vue (child component), if I emit an event on change of input using HTML <input /> element to update the state in the ...

Eslint can cause issues when it comes to declaring types in Typescript

https://i.sstatic.net/qJ4an.png Hey there, I'm currently dealing with this block of code. Every time I try to declare a type, I encounter this error message. Eslint seems to be suggesting that I use a variable instead of returning void. Using //// ...

Transferring information from a Jade file to a Node.js server

I'm currently working on creating a data object within my Jade view page that will be used in my server-side JS. The data object involves dynamic HTML generation that inserts input boxes based on user input. function addDetail() { var det ...

Switch the image displayed on hover over an image using the #map attribute

Recently, I successfully integrated a database connection into this website and made it dynamic. The overall design of the site was already in place, so my main focus was on adding the functionality of the database connection. However, after implementing ...

Guide on loading numerous JavaScript files into a database using the mongo shell

I am faced with the task of loading multiple js files that contain collections creations and seeds into my database using the mongo command. Currently, I have been manually loading data from each file one by one like so: mongo <host>:<port>/< ...