Instructions on invoking a function from one controller within another controller

Is it possible to invoke a function from one controller in another controller? I attempted the following but encountered failure:

<div ng-app="MyApp">
    <div ng-controller="Ctrl1">
        <button ng-click="func1()">func1</button>
    </div>
    <br>
    <div ng-controller="Ctrl2">
        <button ng-click="func2()">func2</button>
    </div>
</div>

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

app.controller('Ctrl1', function($scope) {

  $scope.func1 = function() {
    alert('Ctrl1 and func1')
  }

    $scope.$on("MyFunction", function () {
        alert('Ctrl1 MyFunction')
    });
});

app.controller('Ctrl2', function($scope) {

  $scope.func2 = function() {
    alert('Ctrl2 and func2')
    $scope.$emit("MyFunction");
  }

});

When func2 is called, I used $scope.$emit("MyFunction"); to trigger Ctrl1's MyFunction but it did not work. Is this scenario not feasible?

Please shed some light on this matter.

Answer №1

if you need to communicate with sibling controllers, make sure to capture the event using $rootScope. Here's an example:

$rootScope.$on("MyFunction", function () {
            alert('Ctrl1 MyFunction')
});

Demo

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

app.controller('Ctrl1', function($scope,$rootScope) {

  $scope.func1 = function() {
    alert('Ctrl1 and func1')
  }

    $rootScope.$on("MyFunction", function () {
        alert('Ctrl1 MyFunction')
    });
});

app.controller('Ctrl2', function($scope) {

  $scope.func2 = function() {
    alert('Ctrl2 and func2')
    $scope.$emit("MyFunction");
  }

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp">
    <div ng-controller="Ctrl1">
        <button ng-click="func1()">func1</button>
    </div>
    <br>
    <div ng-controller="Ctrl2">
        <button ng-click="func2()">func2</button>
    </div>
</div>

Answer №2

After your inquiry here about utilizing a service for the solution, I have provided an example.

I have established 2 controllers (FirstCtrl, SecondCtrl) that utilize a common service (Data).

Please take note that the function alertName() is defined within the service, enabling each controller to access it as the service is being injected in both controllers.

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

myApp.service('Data', function() {
  var name = 'Mistalis';
  return {
    alertName: function() {
      alert(name);
    }
  };
});

myApp.controller('FirstCtrl', function($scope, Data) {
  $scope.showName = function() {
    Data.alertName();
  }
});

myApp.controller('SecondCtrl', function($scope, Data) {
  $scope.showName = function() {
    Data.alertName();
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp">
  <div ng-controller="FirstCtrl">
    Controller 1<br/>
    <button ng-click="showName()">Show name from service</button>
  </div>
  <hr>
  <div ng-controller="SecondCtrl">
    Controller 2<br/>
    <button ng-click="showName()">Show name from service</button>
  </div>
</div>

Answer №3

Utilize the $rootScope.$broadcast method:

app.controller('Ctrl1', function($scope) {

  $scope.func1 = function() {
    alert('Ctrl1 and func1')
  }

    $scope.$on("MyFunction", function () {
        alert('Ctrl1 MyFunction')
    });
});

app.controller('Ctrl2', function($scope, $rootScope) {

  $scope.func2 = function() {
    alert('Ctrl2 and func2')
    //$scope.$emit("MyFunction");
    //USE rootScope
    $rootScope.$broadcast("MyFunction");
  }

});

Recommendation: To prevent memory leaks, refrain from using $on listeners on $rootScope. Listeners on $scope will be appropriately destroyed automatically when controllers are removed.

For more details on the AngularJS event bus, refer to

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

jQuery providing incorrect measurements for an element's height

I am encountering an issue with obtaining the height of the #header element in my AngularJS application. Despite using jQuery, the returned height seems to be incorrect. The current code snippet looks like this: $(document).ready(function() { function ...

Access the modal by simply clicking on the provided link

I have implemented a code snippet below to display data from MySQL in a modal popup. Everything is functioning correctly, but I am interested in triggering the modal by clicking a link instead of a button. Is it feasible to achieve this considering I have ...

How can I incorporate eventData when using .bind() for the "keydown" event type?

I want to achieve something like this: var keydownHandler = function (ev) { alert(ev.data.test); return false; } $(document).bind('keydown', {test: 'foo'}, keydownHandler); However, the .bind method doesn't seem to be wor ...

Exploring every conceivable method for accessing a file from a distant server

I am striving to maximize the flexibility of my script, thus I am seeking all potential methods in PHP and JavaScript to access the content (and not the source code) of a PHP file from a remote server. I have come across CURL, fopen, and include for PHP ...

Attempting to add text one letter at a time

Hey there! I'm new to JavaScript and Jquery, and I need some help. My goal is to display text letter by letter when a button is clicked using the setTimeout function. However, I seem to be encountering some issues. Any assistance would be greatly appr ...

What is the method for including an AngularJS expression in element.setAttribute?

How can I add an expression to an element and create a button in a service? Here is the code snippet I currently have: var element = document.createElement('div'); ... element.setAttribute('ng-attr-title', "{{isShowRegionName?'S ...

The HTTP request is malfunctioning in a different location

I'm facing an issue where my code works in the w3schools code editor, but not on localhost or cpanel host. When I try to run it on another host, it gives me a bad request and doesn't return the answer. Here is the code snippet that I am working ...

Guide to integrating jssor into an AngularJS application

Struggling to integrate jssor with angularjs, it seems to be failing because jssor is being initialized before angularjs, causing the ng-repeat elements to not resolve correctly. <div id="slider1_container"> <div u="slides"> <!-- Th ...

The progress indicator for AJAX file uploads is malfunctioning; the addEventListener('progress') method is not functioning as intended

For some reason, the event progress listener isn't firing in AJAX when using Chrome web browser. However, when simply using the form submit function to the form action, the file uploads as expected. Even though the file is uploading behind the scenes ...

Does the frame take precedence over the button?

const div = document.createElement('div'); // creating a dynamic div element div.setAttribute('id', "layer1"); // setting an id for the div div.className = "top"; // applying a customized CSS class div.style.position = "absolute"; // sp ...

Is there a way to "inherit" an attribute from a directive?

Is it possible to extend, share, or reuse functionality in my directive by passing a specific attribute that will be utilized in a tag inside the directive template? <app-autocomplete md-floating-label="Movies"></app-autocomplete> Within my ...

Issue with Axios code execution following `.then` statement

Recently diving into the world of react/nodejs/express/javascript, I encountered an interesting challenge: My goal is to retrieve a number, increment it by 1, use this new number (newFreshId) to create a new javascript object, and finally add this event t ...

Seamlessly transition between various states within a React component for a fluid user experience

I'm currently working on a simple component structured like this: var component = React.createClass({ render: function(){ if (this.props.isCollapsed){ return this.renderCollapsed(); } return this.renderActive() }, ren ...

Erase Photo from Server by Simply Clicking on the Remove Button NodeJS (And Removing the Image Title from the Database)

I have a button that successfully deletes an image name from a mySQL table. However, I also want it to delete the actual image from the server. Below is the code snippet from my index.js: document.querySelector('table tbody').addEventListener(&a ...

Arranging HTML elements using JavaScript or jQuery

Something seems off. The sorting doesn't work as expected. Check out the JavaScript code below: function sortDescending(a, b) { var date1 = $(a).data('date'); var date2 = $(b).data('date'); return date1 > date2; } ...

Issue with Component not displaying properly upon refreshing

I'm currently using react.js and I have a button with an onClick event. My goal is to reload the page after clicking the button and then display a specific component on the page. However, I've encountered an issue where the component doesn't ...

Unable to modify page property status through the Notion API

I've been attempting to use the Notion JS-sdk to update a page's status using their API. However, I've run into some issues that I can't seem to resolve. Updating the status requires modifying the properties object, but no matter what ...

Extending the declaration of JavaScript native methods is not possible when using TypeScript

When attempting to enhance the JS native String class by adding a new method, I encounter error TS2339. interface String { transl(): string; } String.prototype.transl = function() { // TS2339: Property 'transl' does not exist on type 'St ...

Angular Datepicker MinDate function prevents selection of dates "behind" by one

I've encountered an issue with the Angular Bootstrap Datepicker where I'm setting the min-date attribute as follows: <input type="text" class="" uib-datepicker-popup="MM/dd/yyyy" show-button-bar="false" ng-model="vm.date" ng-change= ...

Steps for transferring data from a mock controller to a directive using Jasmine

Attempting to perform unit testing on a directive using Jasmine: app.directive('helloWorld', function() { return { restrict: 'E', scope: { messages: '=', onSelect: '&' }, template: ...