0

My config looks like the following:

app.config(function ($routeProvider) {
    $routeProvider
        ...
        .when('/project/:slug', {
            templateUrl: 'partials/plaintasks-part.php',
            controller: 'ProjectCtrl',
            resolve : {
                projectDetail : ProjectCtrl.loadProject
            }
        })
        ...
});

And loadProject is as follows:

// Project controller
var ProjectCtrl = app.controller('ProjectCtrl', ...);

ProjectCtrl.loadProject = function( $q, Tasks, $route ){

    var defer = $q.defer();

    var slug = $route.current.params.slug;
    // Tasks.getProjectBySlug() is where I have implemented the http request to get the data from server
    var project = Tasks.getProjectBySlug( slug );
    var tasks = Tasks.getProjectTasks( project.id );

    defer.resolve({ 
        tasks : tasks,
        project : project
    });

    return defer.promise;
}

Now the problem is, it doesn't wait for the projects and tasks to be fetched from the server and simply shows the view which I don't want unless the data is fetched from the server. Can anyone please tell me, what am I doing wrong here? Why doesn't it wait for the data to be fetched although I have implemented the resolve in my route?

1
  • Sorry, I was away and wasn't able to post the update! I have got this to work. Thanks to both of you who answered! :-) Commented May 24, 2014 at 10:54

2 Answers 2

1

There are two things wrong in your code:

  • You have an excess deferred (no need for that $q.defer() there, it's the deferred anti pattern.
  • You are not waiting for the promises to resolve when you resolve that deferred.

Since getProjectTasks is not an HTTP call according to the question, it should not return a promise unless there is potential for it to make an HTTP request. If it makes an HTTP request - please write a method on your backend that gets a slug and returns the project and its tasks as the overhead of making two round trips is really expensive.

Then, you can reduce loadProject to:

ProjectCtrl.loadProject = function( $q, Tasks, $route ){
     return Task.getProjectBySlug($route.current.params.slug).then(function(project){
          return {tasks:Tasks.getProjectTasks(project.id), project: project};
     });
};

If you absolutely must make two calls, you can still do:

ProjectCtrl.loadProject = function( $q, Tasks, $route ){  
    var getProject = Task.getProjectBySlug($route.current.params.slug);
    var getTasks = p.then(function(project){ return Tasks.getProjectTasks(project.id);});
    return $q.all([getTasks,getProject]).then(function(project,tasks){
         return {tasks:tasks,project:project};
    });
}

Which still avoids the nesting.

Sign up to request clarification or add additional context in comments.

Comments

1

The problem is with your implementation. You are not resolving the defer correctly. I think that both the Task methods return promise you need to do something like this

Tasks.getProjectBySlug(slug).then(function(project) {
   Tasks.getProjectTasks( project.id ).then (function(tasks) {
      defer.resolve({ 
        tasks : tasks,
        project : project
      });
   })     
});

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.