Tips on creating a reusable function that can be shared among multiple controllers in AngularJS

As a newcomer to angularjs, I have a question about controllers and functions. I understand that typically there is one controller for one view, but multiple controllers can be used for a single view. In my case, I have two controllers in a single view and a function called addComma that I want to make reusable across all controllers on the same view or even different views. How can I make a function in a controller accessible globally throughout my application? Apologies if this seems like a basic question, I'm still trying to grasp the concepts of angularjs.

 app.controller("GetChargesController", function ($scope, GetService, $rootScope) {
    $scope.Title = "Charges Details List";
    $rootScope.loading = true;
    // Call Service Method here
    $scope.GetChargesDetails = GetService.GetAll("CommonApi", "GetChargesDetails").then(function (d) {
        $scope.ChargesDetails = d;
        $rootScope.loading = false;
    });
    // Add comma function here
       $scope.addComma = function(x) {
        return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }

     });

    app.controller("GetPaymentsController", function ($scope, GetService, $rootScope) {
    $scope.Title = "Payments Details List";
    $rootScope.loading = true;
    // Call Service Method here
    $scope.GetPaymentsDetails = GetService.GetAll("CommonApi", "GetPaymentsDetails").then(function (d) {
        $scope.PaymentsDetails = d;               
        $rootScope.loading = false;
    });
    // Add comma function here
    $scope.addComma = function (x) {
        return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
       }

     });

Below is a generic service I've created to retrieve data from a database using asp.net web api. Angular services can hold data so we don't need to repeatedly call the database when navigating between links. For example, if I have Home Link, PaymentCharges Link, and Orders Link on a page, clicking back and forth should not trigger unnecessary database calls. It seems like caching the data would prevent these extra calls.

    app.factory("GetService", function ($http) {
    var thisService = {};

    // Retrieve all data from database
    thisService.GetAll = function (controllername, methodName) {
        var promise = $http({
            method: 'GET',
            url: '/api/'+controllername + '/' + methodName
        })
            .then(function (response) {
                return response.data;
            },
            function (response) {
                return response.data;
            });
        return promise;
    };
});

Answer №1

Develop a utilities service that includes the addComma function. Utilize dependency injection to incorporate the utilities service and utilize the addComma function in the controllers.

app.factory('utilities', function() {
  return {
    addComma: function() {}
  }
});

app.controller("GetChargesController", function ($scope, utilities) {
  $scope.addComma = utilities.addComma;
});

app.controller("GetPaymentsController", function ($scope, utilities) {
  $scope.addComma = utilities.addComma;
});

Answer №2

Here are a couple of strategies to address the service issue:

One approach is to re-use promises by keeping them stored in the service:

 // create an object to store promises
var promises = {};
thisService.GetAll = function(controllername, methodName) {

    promises[controllername] = promises[controllername] || {};
    // if the particular promise doesn't already exist, create it as a property of the above object
    if (!promises[controllername][methodName]) {
      promises[controllername][methodName] = $http({...}).then(...;

    }
    // retrieve and return the specific stored promise
    return promises[controllername][methodName];
 };

Another option is to store the data and utilize $q to generate a new promise that resolves with the stored data if it already exists. Remember to include injecting $q for this method.

var data = {};
thisService.GetAll = function(controllername, methodName) {

  data[controllername] = data[controllername] || {};

  if (data[controllername][methodName]) {
    // data is available for this controller and method, no need for a new request
    return $q.resolve(data[controllername][methodName]);
  } else {
    return $http({...}).then(function(response) {
      // store the retrieved data for future use
      var newData = response.data;
      data[controllername][methodName] = newData;
      return newData;
    });    
  }   

};

Answer №3

Have you considered storing the data in the service for easier access?

One option could be implementing:

.then(function (response) {
    myService.controller.data = response.data
}

This way, you can easily reference the variable in your code using myService.controller.data

Answer №4

One alternative suggestion would be to utilize a structure similar to the one provided below, which could potentially offer greater flexibility. Take a look at the code snippet below:

  1. The appResources-Factory will encompass all the necessary resources for external exposure.
  2. The indexServices-Factory will house your services that correspond with the index controller.

    (function () {
    'use strict';
    var commonServices = angular.module('commonServices', ['ngResource']);
    
    commonServices.factory('appResources', ['$resource',
       function ($resource) {
    
           var indexResource=$resource('/api/index/:id');
            return {
    
                   indexResource:indexResource
    
            }
    }]);
    
     commonServices.factory('indexService',['appResources',
     function (appResources){
    
        var getAllIndexes =function(successCallback){
    
           appResources.indexResource.query({}).$promise.then(
           //success
          function( value ){/*success events and data are captured in 'value'*/
           successCallback(value);
           },
           //error
            function( error ){/*failure events*/}
           )
    
        }
    
       }
      ]);
    });
    
  3. The Controller Method invokes the service and retrieves the data into $scope variables like so:

    (function () {
    'use strict';
     angular.module('saniehhaApp')
        .controller('indexController', indexController);
            indexController.$inject = ['$location', 'indexService'];
                function indexController($location, index,indexService) {
                /* jshint validthis:true */
                        indexService.getAllIndexes(function(successCallback){
                            $scope.value=successCallback;
                        })
                    //$locaton.qwets=....
                    }
    })();
    

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

Have you ever wondered why the Chart is being added to the current div when employing ng-repeat?

I have successfully created a dynamic bar chart and placed it inside a div. However, when I try to achieve the same result using ng-repeat, the new chart is appended to the existing one. Below is my code: HTML: <div id="main" class="drop-container" ...

Checking for the existence of inner directives after they have been rendered in AngularJS

While working on a view, I am using myDirective in the following manner: <div my-directive></div> The myDirective includes a template: <div> <div my-inner-directive></div> </div> My query is: How can I determine ...

numerous items sharing identical key values

I am dealing with an array of objects: [object, object, object, object, object] and I need to assign a unique key to each object based on its title: {test:object, tester:object, foo:object, bar:object, test:object} This way, instead of accessing the ob ...

Totally clueless when it comes to JSON

After diving into tutorials on JSON, the structure and syntax are finally clicking for me. However, I'm currently working on a project that requires a GET, and it seems like JSON could help with this. I've come across comparisons of JSON and AJA ...

Is there a way to arrange an HTML list in this specific manner using CSS or JavaScript?

I need to arrange a list of items in columns with 5 rows each, as shown in the attached image. This list is generated dynamically using an SQL query with a loop on the li tag. I am looking for a solution to order the list in this way using javascript or ...

Steps for adding input controls when clicking on a google map marker popup:

This snippet is designed to display text information when a Google marker is clicked. var infowindow = new google.maps.InfoWindow({ content: "Add your popup content here" }); I am looking to customize this popup window to in ...

What is the best way to enable a function in a component to utilize a factory imported in the constructor?

Struggling to share data between components, I followed this advice on creating a store from this source. While it works smoothly within my component's constructor, I'm having trouble giving the functions similar access. class Home { construc ...

How come attempting to read a nonexistent document from Firestore results in an uncaught promise?

I've been struggling to read and display data from Firestore, but I keep seeing error messages in the console. Encountered (in promise) a TypeError: Unable to read properties of undefined (reading 'ex') Encountered (in promise) a TypeError ...

Preventing child rendering in React until the state is updated: best practices

I'm currently developing a navigation feature that reveals the second tier of options once a menu item is clicked. Below is an example of my code: class App extends Component { constructor(props) { super(props); this.state = { curren ...

Web Browser cross-origin AJAX requests

Recently, I developed an Internet Explorer extension that injects a script every time a page is accessed. The purpose of this script is to send an AJAX request to my localhost. However, I have encountered a roadblock where the request only works if it&apos ...

What is the most graceful method to extract only one dimension from a two-dimensional array using JavaScript or AngularJS?

Is there a more efficient way to extract just one dimension of the array without having to loop through the entire array? In an effort to troubleshoot my problem independently before seeking assistance, I have experimented with filters and loops to extrac ...

"Is it possible to create a for loop that iterates over each individual mesh in a

I'm searching for a way to achieve the following: scene.forEachMeshInScene(function(mesh){ //Perform actions here }); Unfortunately, this capability does not currently exist. Any suggestions on how to accomplish a similar functionality? ...

Error: JQuery's on() function is not defined

After modifying the code in the original and changed code boxes, I'm now encountering an Uncaught Type error: Undefined is not a function. Any thoughts on why this might be happening? Thanks Original: $('.comment').click(function(e){ ...

What is the best location for loading large amounts of data in the MEAN+Mongoose framework?

When it comes to the MEAN stack, where is the ideal level to load bulk data? I have a range of 200 to 800 entries across 2 to 3 different types, each requiring its own Mongoose schema. Here are some options for loading this data (please correct any miscon ...

Tips for utilizing ui-sref in a complex Angular UI router configuration

After spending hours researching and implementing different techniques, I am still unable to solve the issue. My application consists of three main navigations: home, sports, and country. <head> <script src="js/angular-ui-router.min.js"></s ...

Steps to invoke a function repeatedly for an animation

I found this code snippet while browsing a forum post about CSS animations. The question asked if it was possible to create a button that would restart the animation when clicked, even if it is in the middle of playing. They specifically requested no jQu ...

Arrange the Elements of Select Options

I am currently facing an issue with organizing the elements in my select list. I have two interconnected lists, one containing a list of "models" which I have successfully sorted using the following function: var sel = $('#model'); var opts_lis ...

Utilizing the change() and contains() functions with an HTML <select> element in jQuery

Currently, I am working on a feature where images change based on the value selected from a dropdown menu. The code provided below is a simplified version to convey the main idea. Here's the gist of what I have (feel free to ask any questions; please ...

Fetching the Key-Value pairs from a HashMap in JavaScript/AngularJS

I am currently working with a HashMap in the Frontend that is being retrieved from the Backend: var myVar = {"24":{"amount":2,"minutes":30},"32":{"amount":3,"minutes":30}} Can anyone offer guidance on how to access both the keys and values in Javascript ...

Using Javascript to manage controls in three.js

I'm currently experimenting with creating a small game using three.js. Below is the JavaScript code responsible for controlling the game: window.onmouseover = function (ev) { down = true; sx = ev.clientX; sy = ev.clientY; }; window.onmous ...