Encountering a similar issue to the one discussed in:
The $scope variable is undefined unless I forced it to retrieve from service again
AngularJS throws the following error when trying to call a function from a service:
TypeError: $scope.watchlist.addStock is not a function
This is the code snippet for the controller:
angular.module('stockDogApp')
.controller('WatchlistCtrl', function ($scope,$routeParams,$modal,WatchlistService,CompanyService) {
$scope.companies = CompanyService.query();
$scope.watchlist = WatchlistService.query($routeParams.listId);
console.log($scope.watchlist);
$scope.stocks = $scope.watchlist.stocks;
$scope.newStock = {};
var addStockModal = $modal({
scope : $scope,
templateUrl : 'views/templates/addstock-modal.html',
show: false
});
$scope.showStockModal = function(){
addStockModal.$promise.then(addStockModal.show);
};
$scope.addStock = function(){
$scope.watchlist.addStock({
listId : $routeParams.listId,
company: $scope.newStock.company,
shares: $scope.newStock.shares
});
addStockModal.hide();
$scope.newStock = {};
};
Checking the log for $scope.watchlist - the function appears to be present within the object:
Object {name: "Saklep", description: "Saklep", id: 0, stocks: Array[0]}
addStock: function(stock)
arguments: (...)
caller: (...)
length: 1
name: ""
Here's the HTML markup for the modal window:
<div class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" ng-click="$hide()">×</button>
<h4 class="modal-title">Add New Stock</h4>
</div>
<form role="form" id="add-stock" name="stockForm">
<div class="modal-body">
<div class="form-group">
<label for="stock-symbol">Symbol</label>
<input type="text"
class="form-control"
id="stock-symbol"
placeholder="Stock Symbol"
ng-model="newStock.company"
bs-options="company as company.label for company in companies"
bs-typeahead
required>
</div>
<div class="form-group">
<label for="stock-shares">Shares Owned</label>
<input type="number"
class="form-control"
id="stock-shares"
placeholder="# Shares Owned"
ng-model="newStock.shares"
required>
</div>
</div>
<div class="modal-footer">
<button type="submit"
class="btn btn-success"
ng-click="addStock()"
ng-disabled="!stockForm.$valid">Add</button>
<button type="button"
class="btn btn-danger"
ng-click="$hide()">Cancel</button>
</div>
</form>
</div>
</div>
</div>
EDIT: Including the watchlist Service:
angular.module('stockDogApp')
.service('WatchlistService', function () {
var loadModel = function(){
var model = {
watchlists : localStorage['StockDog.watchlists'] ? JSON.parse(localStorage['StockDog.watchlists']) : [],
nextId : localStorage['StockDog.nextId'] ? parseInt(localStorage['StockDog.nextId']) : 0
};
_.each(model.watchlists,function(watchlist){
_.extend(watchlist,WatchlistModel);
_.each(watchlist.stocks,function(stock){
_.extend(stock,StockModel);
});
});
return model;
};
var StockModel = {
save: function(){
var watchlist = findById(this.listId);
watchlist.recalculate();
saveModel;
}
};
var WatchlistModel = {
addStock: function(stock){
var existingStock = _.find(this.stocks,function(s){
return s.company.symbol === stock.company.symbol;
});
if (existingStock){
existingStock.shares += stock.shares;
}else{
_.extend(stock,StockModel);
this.stocks.push(stock);
}
this.recalculate();
saveModel();
},