MrFoh
MrFoh

Reputation: 2701

Backbone View property not being set

I have a view with a property which i want to update its value when i make a fetch request.

    define(['underscore','backbone','models/taskCollection'],
            function( _,Backbone,TaskCollection) {
            var UserTasksView = Backbone.View.extend({
                el:"#user-task-list",
                cur_task: undefined,
                initialize: function() {
                    this.collection = new TaskCollection;
                    this.model = this.collection._model;

                    _.bindAll(this,'render');
                    this.collection.bind('reset',this.render);
                },
view_task: function( event ) {

                var el = $(event.currentTarget);
                var task_id = el.attr('data-taskid');
                var row = el.parents('td').parents('tr.task-row');

                row.addClass("active");

                el.hide();
                el.next('a').show();

                var task = this.collection.fetch({
                    data: {id:task_id},
                    silent:true,
                    success:this._task_fetch_success
                });

                this._show_task_detail();

                event.preventDefault();
            },

            _task_fetch_success: function(response,status,xhr) {
                this.cur_task = JSON.stringify(status);
                return status;
            },

            /**
            * Displays the details of a task
            **/
            _show_task_detail: function() {
                var main = $('.app-content');
                var detail_view = $('.app-extra');
                var task_detail_view = $("#task-detail-view");

                //Reduce task list view width
                main.animate({
                    "width":"50%"
                },2000);
                //Display app extra bar
                detail_view.show();
                //show task detail  view
                detail_view.children('active-page').hide().removeClass('active-page').addClass('inactive-page');
                task_detail_view.show().removeClass('inactive-page').addClass('active-page');
                console.log(this.cur_task);
                var template = ich.task_detail(this.cur_task)
                $('div.task-details').html(template);
            }

The ajax request trigger by the fetch is successful and success callback executes, but when i try to log "cur_task" property, it shows up as undefined; What am i doing wrong

Upvotes: 0

Views: 478

Answers (1)

mu is too short
mu is too short

Reputation: 434615

You have a couple problems that start right here:

var task = this.collection.fetch({
    data: {id:task_id},
    silent:true,
    success:this._task_fetch_success
});

and here:

_task_fetch_success: function(response,status,xhr) {
    this.cur_task = JSON.stringify(status);
    return status;
}

First of all, the success callback is not a jQuery success callback and doesn't receive the usual jQuery parameters; from the fine manual:

The options hash takes success and error callbacks which will be passed (collection, response) as arguments.

so your _task_fetch_success function is called as f(collection, response) not as f(response, status, xhr) as you're expecting; this is why you have to treat the status parameter as JSON: the status is actually the response.

Your next problem is that this isn't what you think it is inside your _task_fetch_success function. Backbone's fetch just calls success as a plain old function:

  var success = options.success;
  options.success = function(resp, status, xhr) {
    collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
    if (success) success(collection, resp, options); // <--------------- Right here
    collection.trigger('sync', collection, resp, options);
  };

That means that this will be window, not your view. The easiest way to work around this problem is to add _task_fetch_success to your _.bindAll list in initialize:

initialize: function() {
    //...
    _.bindAll(this, 'render', '_task_fetch_success');
    //...
}

Upvotes: 1

Related Questions