Can't access $location when using .controller method in AngularJS

Problem

I'm using ng-submit on a form to push data to a Firebase, everything works as expected. What I would like to do is change views at the same time. On the submit button itself I have ng-click set to execute a function using $location. If I place my changeView function in a .controller method I can't utilize $location (specifically, it says - "Error: 'undefined' is not an object (evaluating '$location.path')"). Any help would be super duper.

// This doesn't work and throws the error
myApp.controller('CtrlName', ['$scope', 'angularFireCollection',
    function($scope, angularFireCollection, $location) {

         $scope.changeView = function(view) {
             $location.path(view);
         }

    }
]);



// This works as expected, but I'm name spacing my functions globally and I will have to change how I'm accessing my Firebase, which isn't really desired.   
function CtrlName($scope, angularFireCollection, $location) {

    $scope.changeView = function(view) {
        $location.path(view);
    }

}

Here is my template:

<form role="form" ng-submit="tactics.add(tactic)">
    <div class="form-group">
        <label>Select Method</label>
            <select class="form-control" ng-model="tactic.type">
                <option>Email</option>
                <option>Display</option>
            <option>SMS</option>
            <option>Print</option>
        </select>
    </div>
    <button type="submit" class="btn btn-success" ng-click="changeView('/my-tactics')">Save</button>
</form>
Problem courtesy of: Swordfish0321

Solution

You're not injecting the $location object into your controller. It's listed in your function parameters but you forgot to add it to the list before said function.

myApp.controller('CtrlName', ['$scope', 'angularFireCollection','$location',
    function($scope, angularFireCollection, $location) {
        ...
    }]);
Solution courtesy of: m.e.conroy

Discussion

Holy cow I can't believe I was ever doing this. #Facepalm. Here is the proper way to redirect on a form submission.

Template

<form role="form" ng-submit="vm.submit(tactic)">
    <div class="form-group">
        <label>Select Method</label>
            <select class="form-control" ng-model="tactic.type">
                <option>Email</option>
                <option>Display</option>
            <option>SMS</option>
            <option>Print</option>
        </select>
    </div>
    <button type="submit" class="btn btn-success">Save</button>
</form>

Controller

angular.module('MyApp')
  .controller('CtrlName', function($scope, $location, $log, angularFireCollection, tactics) {

  var vm = this;

  vm.submit = function submit(item) {

    tactics.add(item)
      .then(function(rsp) {
        $log.debug('Attempted to add tactic to Firebase', rsp);
        $location.path('/my-tactics');
      });

  };

  }
);

Notable Changes:

  1. I'm not using annotations for my DI, I offload this to ng-annotate, which then mitigates any issues like the one I ran into when originally asking this question.
  2. I'm using 'controller as' syntax which didn't exist at the time of this question.
  3. I'm no longer creating some weird race condition by trying to execute two separate actions in two separate functions on possibly one event. Promises are a perfect solution for this sort of action.
Discussion courtesy of: Swordfish0321

Also do not forget to add $location into your action:

authControllers.controller('AuthRegisterCtrl', ['$scope', '$http', '$location',

function ($scope, $http, $location) {

    $scope.master = {};

    $scope.save = function (user) {
        $scope.master = angular.copy(user);
        $http({
            method: 'POST',
            url: '/angular/auth/register',
            data: user
        }).success(function (d) {
             $location.path('/login');

        });
    };
}]);
Discussion courtesy of: Вадим

This recipe can be found in it's original form on Stack Over Flow.