4

I'm assuming this is quite straightforward, but how can I have global functions that I can access in my controllers by storing the function in the '.run' phase?

Quite simply, a button is clicked in the DOM that triggers the global function that is called in the appropriate controller..

I've tried various methods and would like a really simple approach to this that helps to minimise the amount of code I've currently got. See below:

**HTML**

<input data-ng-click="clearSignInError()" data-ng-model="email" 
type="email"
id="inputEmail" class="form-control" placeholder="Email address"   
required>

**JS**

app.run(['$rootScope', '$state', function($rootScope, $state) {

    $rootScopecope.clearSignInError = function () {
        $rootScope.loginError = null;
        $rootScope.loginSuccess = null;
    };

}]);

app.controller('loginCtrl', ['$scope', 'Auth', '$state', '$rootScope'
    function($scope, Auth, $state, $rootScope) {

    $rootScope.clearSignInError()

}]);
Daniel
  • 9,491
  • 12
  • 50
  • 66
Richard Ansell
  • 916
  • 1
  • 12
  • 28

2 Answers2

2

Your best bet might be to use Services or Factories, and then inject these as dependencies when needed throughout your application.

Angular Services

Angular Factories

Edit: Added an example service in this plunkr

https://plnkr.co/edit/zqWS9gkTsm2OF1FTb24Z?p=preview

app.service('AuthService', function() {
    this.loginSuccess = function() {
        // do stuff when login is successful
    }

    this.loginError = function() {
        // handle login errors here
    }

    this.clearLoginError = function() {
        console.log("Clear Login Error");
        alert("Clear Login Error");
    }
});

// modified your controller
app.controller('loginCtrl', ['$scope', 'Auth', 'AuthService', '$state', '$rootScope', function($scope, Auth, AuthService, $state, $rootScope) {

    $scope.clearSignInError = AuthService.clearLoginError;

}]);

**HTML**
<input data-ng-click="clearSignInError()" data-ng-model="email"
type="email" id="inputEmail" class="form-control" placeholder="Email address" required>
itsphilz
  • 455
  • 2
  • 9
  • I did try the factory option although I must have got it wrong. Based on my above code, how could i achieve what I need setting up a service? I'm simply removing an error on screen following an incorrect form submission when the user clicks back on the input box. – Richard Ansell Mar 02 '16 at 12:46
  • Just been trying the new code, although I'm getting a red line under $scope.clearSignInError() in my controller? – Richard Ansell Mar 02 '16 at 14:24
  • Sorry that line should be `$scope.clearSignInError = AuthService.clearLoginError();` and the HTML should be `data-ng-click="clearSignInError"` – itsphilz Mar 02 '16 at 14:24
  • Still no luck I'm afraid, I've tried the following: 'app.service('AuthService', function() { this.clearSignInError = function($scope) { $scope.loginError = null; $scope.loginSuccess = null; }; });' and in my controller: '$scope.clearSignInError = AuthService.clearSignInError();' – Richard Ansell Mar 02 '16 at 14:29
  • I have updated my answer with a plunkr for you, so you can see it in action. – itsphilz Mar 02 '16 at 15:04
  • I've just ran through the code and can see how it works, although I'm including a '$scope.loginError = null;' to remove an error message in an ng-if command div (ignore the $scope.loginSuccess = null; as that shouldn't be there!). It just doesn't seem to work as I seem to be getting an injection error pop up in my console, which I think is causing the problems: "Error: [$injector:unpr] http://errors.angularjs.org/1.4.9/$injector/unpr?p0=
    copeProvider%20%3C-%20%24scope%20%3C-%20AuthService
    – Richard Ansell Mar 02 '16 at 15:27
  • That error suggests that you haven't registered AuthService as a provider. How and where are you registering your application? (it will look like `var app = angular.module('myApp', []);` – itsphilz Mar 02 '16 at 15:33
  • Okay, I've had that error before so this may provide more light into my past problems I've had with it. Here's the code: var app = angular.module('routerApp', ['firebase', 'ui.router']); – Richard Ansell Mar 02 '16 at 15:35
  • So long as the `var app = ...` and `app.service(...` are in the same file, or where ever your `app.service(...` is can access `var app` it should just work? If you look in the Plunkr it works fine. – itsphilz Mar 02 '16 at 15:38
  • I will double check again, but I'm not sure if the fact that I'm including $scope in the service is causing the problems. I need to set the ng-if value to null on input click which is the reason I need to have the $scope in the service. – Richard Ansell Mar 02 '16 at 15:41
  • ahh yes, I dont think you can/should include scope in the service, that will error. If you need to set a scope value using the service, you can do as per this updated plunkr - https://plnkr.co/edit/zqWS9gkTsm2OF1FTb24Z?p=preview – itsphilz Mar 02 '16 at 15:51
  • I've tried again with kinds of changes and still no luck. It just seems the function won't trigger using $scope in a factory – Richard Ansell Mar 02 '16 at 15:51
  • Okay, I've just tried that as well with no luck afraid. All I need to do is set the ng-if value on the DOM to null using a globally accessible function using $scope. – Richard Ansell Mar 02 '16 at 16:00
1

You can make use of a factory instead of hooking up with rootScope. In this way, you can include your factory as a dependency in any controller you want. Here's a video demonstration which might help you to get started:

Factories In AngularJS

mehulmpt
  • 15,861
  • 12
  • 48
  • 88
  • If this is the case, I assume I will not need to use all of this code in the factory: $rootScopecope.clearSignInError = function () { $rootScope.loginError = null; $rootScope.loginSuccess = null; };. Instead, I would use $scope.loginError = null; $scope.loginSuccess = null; and store these in a function that is called in the controller using $scope.clearSignInError? – Richard Ansell Mar 02 '16 at 12:51
  • Yes. You can do that. – mehulmpt Mar 02 '16 at 12:54
  • But that's not called using $scope.clearSignInError. Its called using your factory name. – mehulmpt Mar 02 '16 at 12:55
  • I'm trying this now, but I'm also using another 'return' method in my existing factory for another function. It's saying 'unreachable code' at the start of the 'return' method for some reason - everything else seems fine but just want to check this issue out first before trying it. – Richard Ansell Mar 02 '16 at 13:00