Tom
Tom

Reputation: 16246

AngularJS Resolving a Promise

I am learning how to use resolve from an example, and applying it on to my Todo script.

Then I realised an issue, that the example is only showing me how to resolve GET call to get me the Todo List when I first visit this route.

However, in the same route same page I have an Add button to POST new todo item, also a Clear button to DELETE completed items.

Looking at my $scope.addTodo = function() { and $scope.clearCompleted = function () { I want to Resolve my TodoList again after the action. How can I do that?

Here is my code. In my code, the initial resolve: { todos: TodosListResl } is working, it hits TodosListResl function and produces the promise. However, I don't know what to do with addTodo and clearComplete when I want to resolve the todo list again.

enter image description here

main.js

var todoApp = angular.module('TodoApp', ['ngResource', 'ui']);
todoApp.value('restTodo', 'api/1/todo/:id');

todoApp.config(function ($locationProvider, $routeProvider) {
    $routeProvider.when("/", { templateUrl: "Templates/_TodosList.html", 
        controller: TodosListCtrl, resolve: { todos: TodosListResl } });
    $routeProvider.otherwise({ redirectTo: '/' });
});

//copied from example, works great
function TodoCtrl($scope, $rootScope, $location) {
    $scope.alertMessage = "Welcome";
    $scope.alertClass = "alert-info hide";

    $rootScope.$on("$routeChangeStart", function (event, next, current) {
        $scope.alertMessage = "Loading...";
        $scope.alertClass = "progress-striped active progress-warning alert-info";
    });
    $rootScope.$on("$routeChangeSuccess", function (event, current, previous) {
        $scope.alertMessage = "OK";
        $scope.alertClass = "progress-success alert-success hide";

        $scope.newLocation = $location.path();
    });
    $rootScope.$on("$routeChangeError", 
        function (event, current, previous, rejection) {
        alert("ROUTE CHANGE ERROR: " + rejection);
        $scope.alertMessage = "Failed";
        $scope.alertClass = "progress-danger alert-error";
    });
}
//also copied from example, works great.
function TodosListResl($q, $route, $timeout, $resource, restTodo) {
    var deferred = $q.defer();
    var successCb = function(resp) {
        if(resp.responseStatus.errorCode) {
            deferred.reject(resp.responseStatus.message);
        } else {
            deferred.resolve(resp);
        }
    };
    $resource(restTodo).get({}, successCb);
    return deferred.promise;
}
//now, problem is here in addTodo and clearCompleted functions, 
//how do I call resolve to refresh my Todo List again? 
function TodosListCtrl($scope, $resource, restTodo, todos) {
    $scope.src = $resource(restTodo);
    $scope.todos = todos;
    $scope.totalTodos = ($scope.todos.result) ? $scope.todos.result.length : 0;

    $scope.addTodo = function() {
        $scope.src.save({ order: $scope.neworder, 
                          content: $scope.newcontent, 
                          done: false }); 
                        //successful callback, but how do I 'resolve' it?
    };
    $scope.clearCompleted = function () {
        var arr = [];
        _.each($scope.todos.result, function(todo) {
            if(todo.done) arr.push(todo.id);
        });
        if (arr.length > 0) $scope.src.delete({ ids: arr }); 
        //successful callback, but how do I 'resolve' it?
    };   
}

Upvotes: 1

Views: 7948

Answers (1)

Max
Max

Reputation: 8836

I think you're missing the point of resolve. The point of resolve is to " delay route change until data is loaded. In your case, you are already on a route, and you want to stay on that route. But, you want to update the todos variable on the successful callback. In this case, you don't want to use resolve. Instead, just do what needs to be done. For example

$scope.addTodo = function() {
    $scope.src.save({ order: $scope.neworder, 
                      content: $scope.newcontent, 
                      done: false }, function () {
        todos.push({ order: $scope.neworder, 
                      content: $scope.newcontent, 
                      done: false });
    }); 
                    //successful callback, but how do I 'resolve' it?
};

As a side point, I noticed you're using _ most likely from the Underscore library. You don't need to use another library for that because Angular already has $angular.forEach().

Upvotes: 3

Related Questions