0
votes

I have a Compositeview that represents a list of tasks with a header that contains a counter for the tasks in such list.

I have defined an ui hash for the counter to deal with it and to properly initialize it:

The view:

 ui: {
        counter: "#counter",
 },

 onRender: function(){
        this.ui.counter.text(this.collection.length);
 }

The problem I have is that the collection.length is SOMETIMES 0 by the time the collection is rendered. The task models are rendered though. By sometimes, I mean that sometimes the collection.length will have the proper value and sometimes not. This looks like a race condition. However, I make sure the collections are fetched before even creating the views and obviously, before showing them.

A simplified example of my controller looks like:

showTasks: function(){
        //layout
        var kanbanLayout = new View.Layout();

        //tasks
        var backlogFetch = App.request("backlog:task:entities");

        $.when(backlogFetch).done(function(backlogTasks){
             var backlog = new View.Column({
                    collection: backlogTasks,
             });

             kanbanLayout.on("show", function(){
                    kanbanLayout.backlog.show(backlog);
             });

             App.once("fetched:kanban", function(){
                App.mainLayout.mainRegion.show(kanbanLayout);
             });
        }
}   

As you can see, I'm waiting for the data to be fetched, but apparently the code is executed before the data has been fetched. Any ideas of what am I doing wrong?

The full code of my:

As you can see, it is strongly following David Sulc's structure: https://github.com/davidsulc/structuring-backbone-with-requirejs-and-marionette/blob/master/assets/js/apps/contacts/show/show_controller.js#L13

2
Does App.request() really returns Deferred?hindmost
my money is on the request returning something else other than a Deferred, most of the time it's because the request does not exist (either the way it is spelt here does not exist or the js file where the request resides has not been loaded and so has not been setup) and so its just undefined and there for goes straight into runningQuince
yep you guys were right, I was returning the promise in the wrong waymezod

2 Answers

0
votes

You need to define your task entity, otherwise this file is not requested and therefore the handler is not set up

define([
    'app',
    'apps/kanban/show/show_view',
    'entities/task'
], function(App, View){

annoying to spot as marionette will not tell you when you request a handler that does not exist.

0
votes

As @hindmost suggested in the comments, I triple checked if the promise was being properly returned and it was not, the functioning code looks like follows:

var API = {
   getTasks: function(state, kanban_id){
   Entities.tasks = new Entities.TaskCollection([], {'state' : state, 'kanban_id': kanban_id});
   var defer = $.Deferred();
   Entities.tasks.fetch({
       beforeSend: function(xhr) {
           xhr.setRequestHeader('Authorization','token '+App.loggedInUser.token);
       },
       success: function(data){
           defer.resolve(data);
       }
   });
   var promise = defer.promise();
   return promise;
}