MEAN Stack – AngularJS Scope & Controllers – Day 16
The MEAN Challenge Continues!
This video is part of the 30 Day MEAN Stack Honolulu Challenge
In this video we’ll break some code! We’ll look at the Customers Controller and break it up to support Create and Edit functions. We’ll also look at how we can remove the data-ng-init directive and use ‘Controller As’ to give our Controller an Alias.
We look at:
– The List Customers Page that was created from the Yeoman Generator
– Breaking the Customers Controller into 3 parts
– Using ‘this’ instead of ‘$scope’
– The use of the data-ng-init directive
– Removing the data-ng-init directive with ‘Controller As’
– Referring to a scope within our new Controller as an Alias
The functional design post mentioned in this video with the use case, storyboard and wireframes can be found here: Home Page Design.
Hi Shristi,
After changed one controller to three controllers, my list customers page does not work any more. There is an error says:
TypeError: Cannot read property ‘query’ of undefined
It seems Customers is undefined. But my code is same as yours, do you have any idea for the problem?
The following is my code. Thanks in advance!
‘use strict’;
var customersApp = angular.module(‘customers’);
// Customers controller
customersApp.controller(‘CustomersController’, [‘$scope’, ‘$stateParams’, ‘Authentication’, ‘Customers’,
function($scope, $stateParams, $location, Authentication, Customers) {
this.authentication = Authentication;
// Find a list of Customers
console.log( Customers );
this.customers = Customers.query();
}
]);
customersApp.controller(‘CustomersCreateController’, [‘$scope’, ‘Customers’,
function($scope, Customers) {
}
]);
customersApp.controller(‘CustomersEditController’, [‘$scope’, ‘Customers’,
function($scope, Customers) {
}
]);
One thing that stands out is the order of your dependencies. Try removing ‘$location’ from your CustomersController: function($scope, $stateParams, $location, Authentication, Customers).
Angular gets upset when the order or contents of the two parts of the Controller definition are different.
Thanks! It works!
Your answer get me out of few hours comparison with your code. How dare I just overlook this difference! 🙂
Actually I could not use ‘this’ at all. Once I remove: data-ng-init=”find()” it breaks. I need to use $scope, any idea why?
You’ll need to replace data-ng-init=”find()” with the ‘Controller As’ syntax to give Angular context of the Controller to use for the view.
Great, Thanks for the detailed reply
Hi Shristi,
thank you for sharing!
As an Angular noob I was just wondering what the whole benefit is by using ‘this’ instead of ‘$scope’?
Good Question!
In this video, I’ve used ‘this’ to help demonstrate the concept of $scope, but they are different things. I’ve gone down this path primarily for those people who have taken the Angular course over on codeschool (which follows the same convention http://campus.codeschool.com/courses/shaping-up-with-angular-js/intro).
The Angular documentation seems to go back and forth between using ‘$scope’ and ‘this’. $scope is generally the accepted form, and is more powerful, especially when communicating between controllers.
In the Angular documentation on this page: https://docs.angularjs.org/api/ng/directive/ngController , it has examples of both options, and states the following:
-one binds methods and properties directly onto the controller using ‘this’: ng-controller=”SettingsController1 as settings”
-one injects ‘$scope’ into the controller: ng-controller=”SettingsController2″
The second option is more common in the Angular community, and is generally used in boilerplates. However, there are advantages to binding properties directly to the controller and avoiding scope.
– Using ‘controller as’ makes it obvious which controller you are accessing in the template when multiple controllers apply to an element.
– If you are writing your controllers as classes you have easier access to the properties and methods, which will appear on the scope, from inside the controller code.
– Since there is always a ‘.’ in the bindings, you don’t have to worry about prototypal inheritance masking primitives.
Here’s an example:
Using $scope with multiple controllers:
When we use $scope, and want to access the parent controller, we also need to include $parent calls.