After starting my Angular journey, I decided to challenge myself by creating a comprehensive todo app for educational purposes. I seem to be missing something pretty basic, although I can't quite put my finger on it. It seems like there might be an issue with how I've set up my controllers and templates. Despite trying some suggestions from similar queries, none have resolved my problem. Even attempting to use $scope.$apply()
leads to the dreaded "apply/digest already in progress" error.
My setup involves ngRoute so that when a user visits /profile
, it triggers the profileController
and loads templates/profile.html
. The sole purpose of this controller is to establish the current user and attach to $rootScope
. Within the profile view, I've included a nested controller named listController
. This controller receives the List
resource to handle HTTP requests. Everything appears to function correctly regarding routing and GET/POST requests.
Below, I've provided a simplified version of my controller:
var myApp = angular.module('todo', ['ngRoute', 'ngResource'])
// config stuff...
.controller('listController', ['$scope', 'List', 'ngDialog', function ($scope, List, ngDialog) {
// Fetches all lists associated with the current user
$scope.lists = List.query();
// Function to open modal form
$scope.openModal = function () {
ngDialog.open({
template: 'templates/partials/new-list.html',
className: 'ngdialog-theme-default'
});
};
$scope.createList = function () {
List.save({}, {
name: $scope.list.name,
description: $scope.list.description
}).$promise.then(function(result) {
$scope.lists.push(result);
});
};
}]);
The snippet below represents the relevant section of templates/profile.html
, which successfully displays all lists fetched using List.query()
:
<div class="todo-sidebar" ng-controller="listController">
<h3>Your lists <a href="#" ng-click="openModal()"><span>New list</span></a></h3>
<ul>
<li ng-repeat="list in lists">
<a href="#"><span class="list-name">{{list.name}}</span></a>
</li>
</ul>
</div>
The issue arises when I invoke the createList
function from the templates/partials/new-list.html
partial:
<div class="dialog-contents" ng-controller="listController">
<h3>New list</h3>
<form ng-submit="createList()">
<div class="form-group">
<label>Name</label>
<input type="text" name="name" ng-model="list.name">
<textarea name="description" ng-model="list.description" rows="10"></textarea>
<button type="submit" class="button">Create list</button>
</div>
</form>
</div>
While the form submission works flawlessly and adds the new list to the database, the view doesn't update in real-time. Upon inspecting with console.log($scope)
within the promise block, it's apparent that the new list does get appended to the scope.
I suspect that attaching a controller to multiple elements/templates may not be best practice, but I'm unsure about alternative structuring options.