user791134 user791134 - 5 months ago 23
AngularJS Question

Issues converting "controller as" syntax to classic $scope

I have had major issues trying to convert my code from "controller as/this" syntax to classic $scope syntax, without breaking the code. I tried simply replacing "this" with $scope and removing the "controller as" assignments for both controllers, with no luck. I have created a jsfiddle for this with the controller as/this syntax so you can see how it should be working correctly prior to converting the syntax to $scope. https://jsfiddle.net/6zk9vujo/6/
This is another jsfiffle showing the broken code, when I simply replace _this with $scope and remove the controller as assignments in the html https://jsfiddle.net/6zk9vujo/12/ Thank you for your help in advance.

HTML

<div ng-app="app">
<div ng-controller="mainController as main">
<h2>
Main Controller
</h2>
<div>
<table>
<tr>
<td>Item</td>
<td>Price</td>
<td>Quantity</td>
<td></td>
</tr>
<tr ng-repeat="product in main.items">
<td>{{product.name}}</td>
<td>{{product.price | currency}}</td>
<td>
<button ng-click="main.increaseItemAmount(product)">
+
</button>
{{product.quantity}}
<button ng-click="main.decreaseItemAmount(product)">
-
</button>
<button ng-click="main.addToCart(product)">
Add to Cart
</button>
</td>
</tr>
</table>
</div>
</div>
<div ng-controller="cartController as cart">
<h2>
Cart Controller
</h2>
<div>
<table>
<tr>
<td>Item</td>
<td>Price</td>
<td>Quantity</td>
<td></td>
</tr>
<tr ng-repeat="product in cart.cartStorage.items">
<td>{{product.name}}</td>
<td>{{product.price | currency}}</td>
<td>
<button ng-click="cart.increaseItemAmount(product)">
+
</button>
{{product.quantity}}
<button ng-click="cart.decreaseItemAmount(product)">
-
</button>
<button ng-click="cart.removeFromCart(product)">
Remove from Cart
</button>
</td>
</tr>
</table>
</div>
</div>
</div>


JAVASCRIPT

angular.module('app', [])
.factory('cartStorage', function() {
var _cart = {
items: []
};
var service = {
get cartItems() {
return _cart;
}
}
return service;
})
.controller('mainController', function(cartStorage) {
var _this = this;
_this.cartStorage = cartStorage.cartItems;

_this.items = [{
name: 'Apple',
price: 2.5,
quantity: 1
}];

_this.addToCart = function(product) {
_this.cartStorage.items.push(product);
product.addedToCart = true;
}

_this.increaseItemAmount = function(product) {
product.quantity++;
product.showAddToCart = true;
}

_this.decreaseItemAmount = function(item) {
product.quantity--;
if (product.quantity <= 0) {
product.quantity = 0;
product.addedToCart = false;
product.showAddToCart = false;
var itemIndex = _this.cartStorage.items.indexOf(product);
if (productIndex > -1) {
_this.cartStorage.items.splice(productIndex, 1);
}
} else {
product.showAddToCart = true;
}
}
})
.controller('cartController', function(cartStorage) {
var _this = this;
_this.cartStorage = cartStorage.cartItems;

_this.increaseItemAmount = function(item) {
product.quantity++;
}

_this.decreaseItemAmount = function(item) {
item.quantity--;
if (item.quantity <= 0) {
item.quantity = 0;
item.addedToCart = false;
item.showAddToCart = false;
var productIndex = _this.cartStorage.items.indexOf(item);
if (productIndex > -1) {
_this.cartStorage.items.splice(productIndex, 1);
}
}
}

_this.removeFromCart = function(item) {
item.quantity = 0;
item.addedToCart = false;
item.showAddToCart = false;
var productIndex = _this.cartStorage.items.productOf(item);
if (productIndex > -1) {
_this.cartStorage.items.splice(productIndex, 1);
}
}
});

Answer

In the template, remove all main. and cart. and change to ng-controller="mainController" and ng-controller="cartController".

In your controllers, inject $scope and assign it to _this for easiest migration.

.controller('mainController', function($scope, cartStorage) {
    var _this = $scope;

and

.controller('cartController', function($scope, cartStorage) {
    var _this = $scope;

https://jsfiddle.net/6zk9vujo/10/


Alternatively, just replace all _this references with $scope in your controllers.

You also have a bunch of mixed up product / item and productIndex / itemIndex variables. I've standardised them all in this fiddle as well as fixed the logic around re-adding the same product.

https://jsfiddle.net/6zk9vujo/13/

Comments