TypeError: is not a function

I’m building a simple script. I’m trying to not use anonymous functions in jQuery, in order to maintain clean the code. This is the code:

jQuery(function($) {
    'use strict';
    var Call = {
        selection: '',
        init: function() {
            this.product_opt = $('#product_opt');
            this.listenChange();
            //this.test();
        },
        listenChange: function() {
            this.product_opt.live('change', this.afterChange);
        },
        afterChange: function() {
            $("#product_opt :checked").each(function() {
                this.selection = $(this).attr('value');
                console.log( this.selection );
                this.ajax_get_cat();
            });
        },
        ajax_get_cat : function(){
            return $.ajax({
                url: 'http://localhost:8888/mydomain/wp-admin/admin-ajax.php',
                data: {
                    'action': 'show_slider_callback',
                    'selection': this.selection
                },
                success: function(data) {
                    // This outputs the result of the ajax request
                    //console.log(data);
                    console.log('returned' + data);
                },
                error: function(errorThrown) {
                    console.log(errorThrown);
                }
            });
        }
    };

    Call.init();
});

And this is the HTML:

Read More
<div id="product_opt">
    <input id="1" class="selector" type="radio" name="group1" value="6" />  
    <input id="1" class="selector" type="radio" name="group1" value="6" />    </div>

When I try to use the form this is the error message returned in console:

TypeError: this.ajax_get_cat is not a function
this.ajax_get_cat();

Related posts

3 comments

  1. Your problem here is you’re using this.ajax_get_cat within your loop where this actually references each element returned in the selector.

    You’re also making the same mistake when setting this.selection, simply change this to Call and you should be good to go.

    jQuery(function($) {
        'use strict';
        var Call = {
            selection: '',
            init: function() {
                this.product_opt = $('#product_opt');
                this.listenChange();
                //this.test();
            },
            listenChange: function() {
                this.product_opt.live('change', this.afterChange);
            },
            afterChange: function() {
                $("#product_opt :checked").each(function() {
                    Call.selection = $(this).attr('value');
                    console.log( Call.selection );
                    Call.ajax_get_cat();
                });
            },
            ajax_get_cat : function(){
                return $.ajax({
                    url: 'http://localhost:8888/mydomain/wp-admin/admin-ajax.php',
                    data: {
                        'action': 'show_slider_callback',
                        'selection': this.selection
                    },
                    success: function(data) {
                        // This outputs the result of the ajax request
                        //console.log(data);
                        console.log('returned' + data);
                    },
                    error: function(errorThrown) {
                        console.log(errorThrown);
                    }
                });
            }
        };
    
        Call.init();
    });
    

    You can also store a proper reference to this before your loop like so:

    jQuery(function($) {
        'use strict';
        var Call = {
            selection: '',
            init: function() {
                this.product_opt = $('#product_opt');
                this.listenChange();
                //this.test();
            },
            listenChange: function() {
                this.product_opt.live('change', this.afterChange);
            },
            afterChange: function() {
                var _this = this;
                $("#product_opt :checked").each(function() {
                    _this.selection = $(this).attr('value');
                    console.log( _this.selection );
                    _this.ajax_get_cat();
                });
            },
            ajax_get_cat : function(){
                return $.ajax({
                    url: 'http://localhost:8888/mydomain/wp-admin/admin-ajax.php',
                    data: {
                        'action': 'show_slider_callback',
                        'selection': this.selection
                    },
                    success: function(data) {
                        // This outputs the result of the ajax request
                        //console.log(data);
                        console.log('returned' + data);
                    },
                    error: function(errorThrown) {
                        console.log(errorThrown);
                    }
                });
            }
        };
    
        Call.init();
    });
    
  2. Change following portion

    afterChange: function() {
                $("#product_opt :checked").each(function() {
                    this.selection = $(this).attr('value');
                    console.log( this.selection );
                    this.ajax_get_cat(); // this refers to $("#product_opt :checked")
                });
            },
    

    to

    afterChange: function() {
                var self = this;
                $("#product_opt :checked").each(function() {
                    this.selection = $(this).attr('value');
                    console.log( this.selection );
                    self.ajax_get_cat(); //self now refer to Call
                });
            },
    
  3. Inside $(...).each callback, this can’t be both the current element of iteration ($(this)...) and the Call object (this.ajax_get_cat). It is, in fact, the current object; to access the outer this, remember it using the classic var that = this before you start each.

Comments are closed.