Exploring the World of Angular JS Services

Following the recommended practices, I am working on encapsulating my global functions into reusable factory services. In the provided code snippet, my objective is to execute a function that takes the string value of "Qprogress" from my JSON data, performs some mathematical operations on it, and then appends the resulting output to an element with the class "percent". How can I achieve this task effectively?

HTML:

    <table class="table table-striped table-condensed" ng-controller = "clientStatus">
      <thead>
        <tr>
          <th>Client</th>
          <th>Status</th>
          <th>Icon</th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="item in clients">
          <td><a href="#/details/{{clients.indexOf(item)}}" title="Link to {{item.FirstName}} {{item.LastName}}" class="oly-open">{{item.FirstName}} {{item.LastName}}</a></td>
          <td ng-hide="item.Progress == 'In Progress'" ng-class="{ 'status-success': item.Progress == 'Questionnaire Completed', 'status-error': item.Progress == 'Unsent'}">{{item.Progress}}</td>
          <td ng-if="item.Progress == 'In Progress'" class="status-info percent" ng-init="progressCalc(item)"></td>
          <td width="10%"><a href="#/reports/" title{{$index + 1}}="Reports" ng-show="{{item.Progress == 'Questionnaire Completed'}}"><span class="stat-icon-report"></span></a> <a href="#/sends/{{$index + 1}}" title="Alert" ng-show="{{item.Progress == 'Unsent'}}"><span class="stat-icon-bullhorn"></span></a> <a href="#/progress/{{$index + 1}}" title="In Progress" ng-show="{{item.Progress == 'In Progress'}}"><span class="stat-icon-phone"></span></a></td>
        </tr>
      </tbody>
    </table>

AngularJS:

    var myApp = angular.module('myApp', []);

    myApp.factory('progressCalc', function() {
      angular.forEach(function(item) {
        var m = 0.26664;
        var s = 0.26664;
        var i = 0.694375;
        var t = item.Qprogress;
        t = t.replace(/m/g, '');
        t = t.replace(/s/g, '');
        t = t.replace(/i/g, '');
        var ta = t.split("/");
        var tTotal = (ta[0] * m) + (ta[1] * s) + (ta[2] * i);
        Math.round(tTotal);
        (tTotal + '%').append('.percent');
      });
    });
    myApp.controller('clientStatus', ['$scope', '$http', function($scope, $http) {
      $http.get('assets/js/lib/angular/clientList.json').success(function(data) {
        $scope.clients = data;

      });
    }]);

Snippet of JSON:

    {
      "FirstName": "Jane",
      "LastName": "Greenberg",
      "Company": "Nike",
      "CompanyId": "2345672",
      "ClientId": "EFTGE6",
      "Title": "CIO",
      "Phone": "555-555-5555",
      "ClientSystemStatus": "Active",
      "CreationDate": "06/12/2015, 9:12:27 am",
      "Progress": "In Progress",
      "Qprogress": "m125/s108/i0",
      "Email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="670d0015020209050215002709...">
    }

I initially attempted to enclose my code within a function and use ng-init on the target element for appending, but unfortunately, that approach did not yield the desired results.

Answer №1

To ensure reusability, your factory should return a component that the controller can utilize. The calculations are performed within the factory, with the controller simply invoking it and passing the results to the DOM (consider utilizing a directory for better organization).

// Defining the factory which will provide the 'doMath' method
myApp.factory('progressCalc', function() {
return {
    doMath: function(data) {
        // Array to store calculation results
        var values = [];

        angular.forEach(function(data) {
            var m = 0.26664;
            var s = 0.26664;
            var i = 0.694375;
            var t = item.Qprogress;
            t = t.replace(/m/g,'');
            t = t.replace(/s/g,'');
            t = t.replace(/i/g,'');
            var ta = t.split("/");
            var tTotal = (ta[0] * m) + (ta[1] * s) + (ta[2] * i);
            Math.round(tTotal);

        values.push(tTotal + '%');

        });
        // Returning the calculated values to the controller
            return values;
        }
    }
});

// Controller implementation
myApp.controller('clientStatus', ['$scope', '$http', 'progressCalc', function($scope, $http, progressCalc) { 

    //...other functionality

    $http.get('assets/js/lib/angular/clientList.json').success(function(data) { 

        // Processing the data and invoking the progressCalc factory
        $scope.clients = progressCalc.doMath(data);

      // Example of additional actions

      $scope.clients.forEach(function(item){
        item.append('.percent')
      });
    });

});

Answer №2

When working on your function, it is essential to implement a few modifications (refer to the initial response).

angular.forEach(function(data) {

This should be updated to:

angular.forEach(data, function(item) {
...
tTotal = Math.round(tTotal);
...

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

Activate only one option group at a time

<select name="location"> <optgroup label="West Coast"> <option value="1">Los Angeles</option> <option value="2">San Francisco</option> <option value="3">Seattle</option> &l ...

The caret operator in NPM does not automatically install the latest minor version of a package

Within my package.json file, one of the dependencies listed is labeled as... "@packageXXX": "^0.7.0", Upon running the "npm outdated" command, I observed that... @packageXXX current: 0.7.0 wanted: 0.7.0 latest: 0.8.0 Despite executing "npm ...

What is the best way to reset a JSON response in a clean manner

I need to reset the previous responses. They are starting to accumulate. Unfortunately, I don't have much experience with ajax. I am grateful for all the responses. Thank you. https://i.stack.imgur.com/WKQhc.png <script type="text/javascript"> ...

Unable to store loop information fetched from api into a JSON file

I'm currently facing an issue with my code where I am trying to save the results from looping through an API into a JSON file using writeFileSync. Here is the code snippet in question: function processRarity(limit) { var resultJson = []; for ( ...

Utilizing Nested JSON for Stacked Highcharts Implementation

I've been researching extensively about nested json for Highcharts stacked percentage column, but I haven't been able to get the desired output. Below is the code that I have tried, but unfortunately it's not producing the expected result. ...

AngularJS: Organizing elements across multiple ng-repeats

UPDATE: Here is a link to the plunker I created. In my JSON string, I have 2 parent objects with children. { "ParentA": { ... }, "ParentB": { ... } } Both ParentA and ParentB have children with some overlapping names. I ...

Error alert: The function is declared but appears as undefined

Below is the javascript function I created: <script type="text/javascript"> function rate_prof(opcode, prof_id) { $.ajax({ alert('Got an error dude'); type: "POST", url: "/caller/", data: { ...

What is the best method for simultaneously listening to several events?

For instance, I am interested in setting up a situation where a callback is triggered only when ALL specified events occur: on(['aEvent', 'bEvent', 'cEvent'], callback) The callback function should receive an array (or objec ...

Switching from React version 15.6.2 to 16 results in disruptions to the functionality of the web

Currently, I am encountering an issue where none of my index.js files are rendering. After using the react-scripts to build my web application in version 16.2.0, I receive an error stating that r.PropTypes is undefined when trying to access the localhost a ...

Arrange the child elements of a div to be displayed on top of one another in an HTML document

I am struggling with a div containing code .popupClass { width: 632px; height: 210px; position: absolute; bottom:0; margin-bottom: 60px; } <div class="popupClass"> <div style="margin-left: 90px; width: 184px; hei ...

What is the best way to transfer scope to a callback function in the context of node-mysql?

When running the code below, I encounter an error that says client is not defined: var mysql = require('mysql'); var conf = { 'database':'database', 'user':'user', 'password':'password ...

Ways to call a DIV element in a PHP file from a different PHP file

I am facing an issue with referring to a specific <div> element from one .php page to another. The current code is redirecting me to the home page of the first page, instead of displaying the desired content. Can anyone provide guidance on how to ach ...

Determining array size with the help of a jsonpath expression - The expert in JsonPath, Stefan

Currently, I'm facing an issue while attempting to determine the size of an array or list using Stefan Goessner's JsonPath. The version I am utilizing is json-path-2.0.0. My JsonPath expression is $.orders.length and the JSON data resembles the ...

Creating CSS boxes in a dual column layout with a step-by-step approach

Currently, I am in the process of developing a user interface for a menu that looks something like this: I am exploring different implementation methods for this design. In this project, I am utilizing Bootstrap framework. The main container is a containe ...

Discover an Element within a JSON Array and Append a New Value to it

I've got an array of JSON data structured like this: [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Eve' } ] My goal is to locate an object by its id and append a ...

Which is better: specifying a name in window.open() or using replace?

If the current window is www.myparent.com and a button labeled "a" is clicked, it triggers the following function window.open('children','same','',??). Subsequently, a new page will open as www.myparent.com/children. On the o ...

Minimizing switch-case statement into inactive input field (AngularJS)

While the code statement functions as intended, it may not be considered best practice due to the repetition of variables in each case of the switch statement. I am unsure of how to streamline the code or if there is an alternative to using a switch statem ...

While loop not yielding immediate result with asynchronous function

As a beginner in Node.js, I have successfully connected an LCD Panel and a 4x4 Membrane matrix keypad to my Raspberry Pi. Using Node.js, I have programmed them to work together. My goal is to have the LCD panel immediately display any key pressed on the ke ...

Guide on Executing a Callback Function Once an Asynchronous For Loop Completes

Is there a way to trigger a callback function in the scan function after the for await loop completes? let personObj = {}; let personArray = []; async function scan() { for await (const person of mapper.scan({valueConstructor: Person})) { ...

Retrieving and submitting text in a NodeJS environment

I'm attempting to retrieve text from an API that only provides a string of text ((here)), but I am encountering difficulties in displaying it accurately. When I try to post it, the output shows as [object Response], and the console.log is not showing ...