Utilizing API data sharing across AngularJS controllers

I am facing a challenge with my parent controller and its children controllers, as I want them all to share the data fetched from an Api service.

Controllers:

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

app.controller('main', ['$scope', 'Api', function($scope, Api) {
    var getList1 = Api.getList1()
      .then(function(resp) {
        $scope.list1 = resp.data;
      });

    var getList2 = Api.getList2()
      .then(function(resp) {
        $scope.list2 = resp.data;
      });
}]);

app.controller('child1', ['$scope', function($scope) {
    $scope.list1 = ?
    $scope.list2 = ?
}]);

app.controller('child2', ['$scope', function($scope) {
    $scope.list1 = ?
}]);

View:

<div ng-controller="main">
    <ul>
        <li ng-repeat="list in list1">
            {{list.item}}
        </li>
    </ul>
    <div ng-controller="child1">
        <ul>
            <li ng-repeat="list in list1">
                {{list.item}}
            </li>
        </ul>
        <ul>
            <li ng-repeat="list in list2">
                {{list.item}}
            </li>
        </ul>
    </div>
    <div ng-controller="child1">
        <ul>
            <li ng-repeat="list in list1">
                {{list.item}}
            </li>
        </ul>
    </div>
</div>

I attempted to implement this solution using Angular's events mechanism ($on, $emit).
I encountered difficulty in determining which child controller is active and passing the data once the promise is resolved. This led to messy spaghetti code...

Answer №1

If you're looking for the optimal method, consider utilizing a service to manage your API operations within your application. Take a look at this fiddle for insights on how to achieve your desired functionality. By leveraging AngularJS services, you can seamlessly share data, objects, and functions across controllers, fostering seamless interaction regardless of the number of controllers in your app.

The example below showcases a comprehensive API service integrated with actual HTTP requests and an AngularJS service handler. Incorporate this logic into your application for effective implementation. Be sure to explore the demo in the fiddle demo.

View

<div ng-controller="MyCtrl">
   <h1>
    MyCtrl
   </h1>
   <button ng-click="clearData()">
    Clear data by using MyCtrl
   </button>
   <div ng-repeat="user in users">
     <p>
       Username: {{ user.name }}
     </p>
   </div>
</div>
<br /><br />
<div ng-controller="MyOtherCtrl">
 <h1>
  MyOtherController
 </h1>
   <button ng-click="clearData()">
    Clear data by using MyOtherController
   </button>
   <div ng-repeat="user in users">
     <p>
       Username: {{ user.name }}
     </p>
   </div>
</div>

AngularJS Application

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


myApp.controller('MyCtrl', function ($scope, apiService) {
   $scope.users = apiService.getResponseData();
   $scope.$watch(function () { return apiService.getResponseData()}, function (newValue, oldValue) {
     $scope.users = newValue
   });

   $scope.clearData = function () {
        apiService.reset();
   }
});
myApp.controller('MyOtherCtrl', function ($scope, apiService) {

   apiService.loadData();

   $scope.$watch(function () { return apiService.getResponseData()}, function (newValue, oldValue) {
     $scope.users = newValue
   });

   $scope.clearData = function () {
        apiService.reset();
   }
})


myApp.service('apiService', function ($http) {

  var responseData = null;

  return {
    loadData: function () {
      return $http({
         url: 'https://jsonplaceholder.typicode.com/users',
         method: 'GET'
      }).then(function (response) {
         responseData = response.data
      });
    },
    getResponseData: function () {
       return responseData
    },
    reset: function () {
       responseData = null;
    }
  }
});

Answer №2

When your data resides within the parent controller, you have the ability to retrieve it in child controllers using the $scope.$parent method:

app.controller('child2', ['$scope', function($scope) {
    $scope.data1 = $scope.$parent.data1;
    $scope.data2 = $scope.$parent.data2;
}]);

Answer №3

Create directives for your children, allowing you to inject data into the scope.

yourModule.directive('child2', function() {
    return {
       scope: {items:'=',
       controller: function (scope) {
           //consider adding a controller for extra functionality
           scope.doSomething =  function() {
              //access items from the scope here
           }
       },
       template: '<ul><li ng-repeat="item in items">{{item.name}}<li><ul>'
    }
}

Usage:

<child2 items="items"></child2>

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

update value asynchronously

My implementation involves a dialog controller: .controller('loadingDialogCtrl', function($scope, $mdDialog, $rootScope, loadingDialog) { $scope.loadingDialog = loadingDialog; }); In another controller, I use the dialog controller and manip ...

Transferring JSON information from Express to Backbone

I have developed a basic Backbone application and am trying to integrate JSON data from a MYSQL database using an Express server. However, when I make a GET request with Express to fetch data for Backbone, the html template in Backbone disappears, leaving ...

Explore by the anchor tag

I've recently implemented a search bar utilizing Bootstrap. This is the code for the search bar: <div class="md-form mt-0"> <input class="form-control" id="myInput" type="text" placeholder="Sear ...

Simulating Cordova plugin functionality during unit testing

I have a code snippet that I need to test in my controller: $scope.fbLogin = function() { console.log('Start FB login'); facebookConnectPlugin.login(["public_profile", "email", "user_friends"], FacebookServices.fbLoginSuccess, FacebookServic ...

Incorporate AngularJS expressions into your Google Map embedding for enhanced customization

Having trouble incorporating an AngularJS expression into a Google Maps embed. Here is the snippet of code I have: <iframe width="240" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.com/maps?f=q& ...

Sending data through forms

I'm having trouble storing values input through a dropdown menu in variables event1 and event2, despite trying global declarations. How can I successfully store a value to both variables and pass it to the JavaScript code? Thank you. <!DOCTYPE HT ...

Retrieve the value from every dynamically generated text box by its corresponding number

Trying to create a new Online Quiz System. The challenge I'm facing is extracting the values of each option associated with a specific question number. For example: Question # 1: a. elephant b. lion c. zebra Question # 2: a. green b. ...

The concept of abstraction levels within providers, services, and factories in AngularJS

During a recent interview, I was posed with the following question: out of $provider, $service and $factory, which one offers the lowest level of abstraction? While I have experience using all three, my understanding is limited to the syntactic differences ...

Safari browser removes spaces after commas in cookie values

I'm encountering an issue when trying to set a session cookie for storing an Address. It seems that whenever I include a comma followed by a space in the cookie's value, Safari automatically removes the spaces after the commas, causing the format ...

The most effective method for acquiring an object through inheritance

I'm seeking advice on the best practice for adding behavior to an object received as a JSON object. I have REST services that allow me to define a sort of state machine. The API defines a /sessions resources. When creating a session via POST /sessio ...

Keep moving forward in Sailsjs even after sending back a response with res.json();

It will keep running even if the condition is met and the code inside return res.json() gets executed. _.each(rooms, function(room){ if(room.users.length == users.length) { return res.json(room); // <-- returns but execution continues } ...

Sending a prop to a handler causes issues with navigation paths

I'm facing an issue with my handler and button component setup. Here's my handler: const addToCartHandler = (id) => { navigate(`/cart/${brand}/${id}?qty=${qty}`)}; And here's the button component using the handler: <Button onClick={a ...

Adjusting the color of a specific part of a text within a string using

I am trying to update the color of specific keywords within a post. For example: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam tempor lacinia urna eget gravida. Quisque magna nulla, fermentum fermentum od #keyword1 #keyword2 #keyword3 ...

Tips for deploying a Nuxt application using an alternative command line interface

Despite my best efforts scouring the internet for a solution, I have yet to find a method to resolve my issue. The problem lies with my nuxt.js SPA being blocked by my company firewall when accessed by other users at the designated host/port. While servin ...

Tips for managing CSS/style conflicts in JavaScript/AngularJS applications

I am new to AngularJS and I have a requirement to assign CSS properties to a component at the JavaScript file level. When I debug my code after applying the CSS styles to the component, I can see that all the applied CSS properties are behaving as expected ...

Transitioning from Three.js's CanvasRenderer to WebGLRenderer is a significant upgrade

Can a Three.js script created with CanvasRenderer be easily converted to use WebGLRenderer instead, and if yes, what is the process for doing so? ...

Properties of the State Object in React Redux

I'm curious as to why my state todos were named todo instead of todos in the redux dev tools. Where did that name come from? There is no initial state, which makes me wonder. I'm currently following a Udemy course by Stephen Grider, but I am wor ...

Why is the leading zero being ignored when I try to print the contents of the session in PHP?

Encountering an issue with printing the content session. The problem arises when creating the session, as the variable is initially in string format (varchar obtained from a mysql field): Initial variable: 09680040 Printed with alert or displayed in div: ...

The web server is now serving Index.html instead of main.js for AngularJS 2

Transitioning from an angular1 application to an angular2 one, I encountered an error after removing the ng-app directive and adding the system.config: Error: SyntaxError: Unexpected token < Evaluating https://localhost:8080/contents/app/main.js Error ...

What is the best way to extract the text from a <div> tag and show it in a different div when clicked on using ng click in AngularJS?

When the button is clicked, the text in ng-model=name should be displayed in the <h2> tag. <div ng-model="name">This is a text</div> <button ng-click="getname()">Click</button> <h2>{{name}}</h2> ...