1. #1
    Sencha User
    Join Date
    Nov 2011
    Posts
    33
    Vote Rating
    0
    tomas.fejfar is on a distinguished road

      0  

    Default Answered: Function replaced with object?! Error when dispatching

    Answered: Function replaced with object?! Error when dispatching


    Strange thing happened to me today. The above message started displaying. I have a controller that list presentations. It has actions index (=list), detail and play (that plays the slideshow). I can repeat the dispatch transition from list to detail and back as many times I want. But when I dispatch the play action and return back to detail, I can't return there any more, because of an error:

    Uncaught TypeError: Object [object Object] has no method 'call'

    I examined what happens. Problem is that in the first call in the next code (sencha-touch.debug.js:line 10630) "controller[action]" is a function - the contents of function written in controller class.

    Code:
    if (controller && action) {
        controller[action].call(controller, interaction);
        interaction.dispatched = true;
    }
    But after that when i dispatch the action second time, there is no function anymore. It's been replaced with an object (looks like the view panel). And "call" method does not work on it. What am I doing wrong, that the function is replaced with an object?

    Here is my Controller's code:

    Code:
    Ext.regController('videos', {    index : function(options) {
            if (!this.listPanel) {
                this.listPanel = new app.views.VideoList({
                    listeners : {
                        list : {
                            select : function(list, record) {
                                Ext.dispatch({
                                    controller : 'videos',
                                    action : 'show',
                                    list : list,
                                    record : record,
                                    historyUrl : 'videos/show/' + record.get('id'),
                                    animation : {
                                        type : 'slide'
                                    }
                                });
                            },
                            scope : this
                        },
                        activate : function() {
                            if (this.detail) {
                                this.detail.destroy();
                            }
                            if (this.play) {
                                this.play.destroy();
                            }
                        }
                    }
                });
            }
            this.application.viewport.setActiveItem(this.listPanel,
                    options.animation);
            this.application.currentItem = 2;
        },
        show : function(options) {
            if (!options.record) {
                Ext.dispatch({
                    controller : 'videos',
                    action : 'index',
                    historyUrl : 'videos/index'
                });
                return;
            }
            this.record = options.record;
            options.list.deselectAll();
            console.log('detail created');
            this.detail = new app.views.VideoDetail({
                data : this.record.data,
                listeners : {
                    el : {
                        tap : function() {
                            console.log('element tapped');
                            console.log('record is', this.record);
                            Ext.dispatch({
                                        controller : 'videos',
                                        action : 'play',
                                        historyUrl : 'videos/play/'
                                                + this.record.get('id'),
                                        animation : {
                                            type : 'slide',
                                            direction : 'left'
                                        }
                                    });
                        },
                        scope : this,
                        delegate : '.video-disclose'
                    },
                    deactivate : function(component) {
                        console.log('detail destroyed');
                        component.destroy();
                    }
                }
            });
    
    
            this.detail.query('#backButton')[0].on({
                tap : function() {
                    Ext.dispatch({
                        controller : 'videos',
                        action : 'index',
                        historyUrl : 'videos/index',
                        animation : {
                            type : 'slide',
                            direction : 'right'
                        }
                    });
                },
                scope : this
            });
    
    
            this.application.viewport.setActiveItem(this.detail, {
                type : 'slide'
            });
        },
        play : function(options) {
            if (!options.record) {
                if (!this.record) {
                    Ext.dispatch({
                        controller : 'videos',
                        action : 'index',
                        historyUrl : 'videos/index'
                    });
                    return;
                }
            } else {
                this.record = options.record;
            }
            console.log('play created');
            this.play = new app.views.VideoPlay({
                data : this.record.data,
                listeners : {
                    deactivate : function(component) {
                        console.log('play destroyed');
                        component.destroy();
                    }, 
                    beforerender : function() {
                        console.log('beforerender event fired');
                        this.store.load({
                            scope : this,
                            callback : function(records, operation, success) {
                                Ext.each(records, function(record) {
                                    this.carousel.add(new Ext.Component({
                                        'tpl' : app.partials.videoPlayCarouselItem,
                                        'data' : record.data
                                    }));
                                }, this);
                                this.carousel.doLayout();
                            }
                        });
                    },
                    show : function () {
                        Ext.each(this.carousel.items.items, function(item) {
                            console.log(item);
                            item.el.on('tap', function() {
                                console.log('tap item fired');
                                me.play.toolbar.show();
                                me.doComponentLayout();
                            });
                        });
                    }
                }
            });
    
    
            this.play.query('#VideoPlayBackButton')[0].on({
                tap : function() {
                    Ext.dispatch({
                        controller : 'videos',
                        action : 'show',
                        historyUrl : 'videos/show/' + this.record.get('id'),
                        animation : {
                            type : 'slide',
                            direction : 'right'
                        }
                    });
                },
                scope : this
            });
    
    
            this.play.query('#VideoPlayHideButton')[0].on({
                tap : function() {
                    me = this;
                    this.toolbar.hide({
                        type : 'slide',
                        direction : 'down'
                    });
                    this.toolbar.on('hide', function() {
                        console.log('hide event fired');
                        me.doComponentLayout();
                    });
                },
                scope : this.play
            });
    
    
            this.play.carousel.on({
                afterrender : function(c) {
                    console.log(c.items.getCount());
                    console.log('afterrender event fired');
                    me = this;
                    console.log(c.items);
                    Ext.each(c.items, function(item) {
                        console.log(item);
                        item.el.on('tap', function() {
                            console.log('tap item fired');
                            me.play.toolbar.show();
                            me.doComponentLayout();
                        });
                    });
                }
            });
            this.application.viewport.setActiveItem(this.play, options.animation);
        }
    });
    And the view that I want to show:
    Code:
    app.views.VideoPlay = Ext.extend(Ext.Panel, {
        store : app.stores.presentations,
        initComponent : function() {
            this.carousel = new Ext.Carousel({
                itemId : 'videoPlayCarousel',
                tpl : app.partials.videoPlayCarouselItem
            });
            this.audio = new Ext.Audio({
                url : this.data.url,
                autoPause : true,
                autoResume : true
            });
            this.toolbar = new Ext.Toolbar({
                //floating : true,
                top : 0,
                items : [ {
                    xtype : 'button',
                    ui : 'back',
                    text : 'Zpět',
                    itemId : 'VideoPlayBackButton'
                }, {
                    xtype : 'button',
                    text : 'Skrýt panel', 
                    itemId : 'VideoPlayHideButton'
                } ], 
                itemId : 'playerToolbar'
            });
            this.items = [ this.carousel, this.audio ];
            this.dockedItems = [ this.toolbar ];
            Ext.apply(this, {
                layout : 'fit',
            });
            app.views.VideoPlay.superclass.initComponent.apply(this, arguments);
        }
    });
    Ext.reg('video-play', app.views.VideoPlay);

  2. Got it... in your play method in your controller, you set this.play to new app.views.VideoPlay which is overwriting the play method as the scope (this) is the controller.

  3. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,347
    Answers
    3542
    Vote Rating
    846
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    Where is your Ext.dispatch call that this is happening? Are you setting something onto the Controller?
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  4. #3
    Sencha User
    Join Date
    Nov 2011
    Posts
    33
    Vote Rating
    0
    tomas.fejfar is on a distinguished road

      0  

    Default


    The dispatch is in a listener (first part of code above):

    Code:
    this.detail = new app.views.VideoDetail({
                data : this.record.data,
                listeners : {
                    el : {
                        tap : function() {
                            console.log('element tapped');
                            console.log('record is', this.record);
                    Ext.dispatch({
                                        controller : 'videos',
                                        action : 'play',
                                        historyUrl : 'videos/play/'
                                                + this.record.get('id'),
                                        animation : {
                                            type : 'slide',
                                            direction : 'left'
                                        }
                                    });
                        },
                        scope : this,
                        delegate : '.video-disclose'
                    },
    ...

  5. #4
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,347
    Answers
    3542
    Vote Rating
    846
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    Got it... in your play method in your controller, you set this.play to new app.views.VideoPlay which is overwriting the play method as the scope (this) is the controller.
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  6. #5
    Sencha User
    Join Date
    Nov 2011
    Posts
    33
    Vote Rating
    0
    tomas.fejfar is on a distinguished road

      0  

    Default


    *DOH* Thanks a million! I was not able to track this down. I still can'twrap my mind arout this javascript feature that you can replace "method" with "member variable" Thx again

  7. #6
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,347
    Answers
    3542
    Vote Rating
    846
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    Javascript doesn't have any protection for stuff like that. You can overwrite anything with anything.
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

Thread Participants: 1