Explain Codes LogoExplain Codes Logo

Angularjs: How can I pass variables between controllers?

javascript
angularjs
javascript-best-practices
event-driven-programming
Anton ShumikhinbyAnton Shumikhin·Jan 29, 2025
TLDR

Best way to exchange data between controllers in AngularJS is to use a service. Below is a boilerplate you can easily adapt to your needs.

// Shared service skeleton app.service('SharedVars', function() { var store = {}; this.set = function(key, value) { store[key] = value; /* You just got served! */} this.get = function(key) { return store[key]; /* Get or regret! */}; }); // Applying it in the controllers app.controller('CtrlA', function(SharedVars) { SharedVars.set('sharedKey', 'value'); // With great keys come great values! }); app.controller('CtrlB', function($scope, SharedVars) { $scope.sharedValue = SharedVars.get('sharedKey'); // A key to rule them all! });

This setup lets you effortlessly read, write, and modify shared variables in your controllers by injecting the SharedVars service.

Bind to Variables, not Trouble

Mind the dot in your binds! Functionality can become compromised if you forget to use a single dot in your bindings. This will guard against child scopes inadvertently creating properties on the parent scope, thus bypassing prototype-related concerns.

// In service this.sharedObject = { someValue: '' }; // It's Object-ive sharing! // In controller $scope.model = SharedVars.sharedObject; // "SharedVars.sharedObject and I used to date." - $scope.model // In template <input ng-model="model.someValue"> // Keep it secret, keep it safe

Even though $rootScope might seem as a universal remedy, it often leads to coupling issues and debug nightmares due to unintentional cluttering of the scope. Here is where services or factories play their part in preserving reusability and modularity.

Building Factories Faster than Elves

You can use factories for the same purpose while giving you the benefit of lazy instantiation, or in layman terms, it sets up your shared data only when it's needed first. No wastage of memory!

// Factory Blueprint app.factory('SharedData', function() { var data = { key: null }; // This *** key ain't loyal return { get key() { return data.key; }, // "Knock, knock." "Who's there?" "Key." "Key who?" "Key for data retrieval." set key(newVal) { data.key = newVal; } // Wherever there's a Key, there's a way! }; }); // Factory usage in different controllers app.controller('CtrlC', function($scope, SharedData) { SharedData.key = 'newValue'; }); app.controller('CtrlD', function($scope, SharedData) { $scope.value = SharedData.key; });

Beware that factories offer an extra layer of control and are suitable for more complex application architectures compared to services.

Communicating Controllers through Event

The $broadcast, $emit, and $on methods can be used to send updates about data changes to other parts of your application in an event-driven manner.

app.controller('CtrlE', function($scope) { $scope.doSomething = function() { $scope.$emit('dataUpdated', someData); // Emitting Diplomatic Mail }; }); app.controller('CtrlF', function($scope) { $scope.$on('dataUpdated', function(event, receivedData) { // Use the updated data }); });

However, such heavy use of events can introduce complexities to your unfamiliar Angular code. So, think twice before deciding the path of events.

Code Style Tips and Your Sanity

Here are some instructor-grade best practices:

  1. Object properties: Bind to object properties to prevent child scopes from overshadowing parent scopes.
  2. Global data: Use $root sparingly. It's the telltale sign of global data which should be an exception, not a norm.
  3. Clarity: Invest time in commenting and documenting. They make your application easier to maintain and describe how data sharing is performed.
  4. Efficiency: For complex cases, hashtables within services can help manage states and references efficiently.