Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing `this` in Ajax callback, all within an Object

I'm dealing with a problem about an Ajax callback inside of an Object. Please consider this code :

Search.prototype =
{
    ask : function( query )
    {
        // Display loader
        $('.loader').show();

        $.ajax({
            dataType : 'jsonp',
            type : 'GET',
            url : 'http://api.deezer.com/search/track/',
            data : {
                output : 'jsonp',
                q : query
            }
        }).done(function(res) {

            this.loadResults( res );
            // [Error] Object success has no method 'loadResult'

        });
    },

    loadResults : function (res)
    {
        // Hide loader
        $('.loader').hide();

        console.log( res );

        // doing some stuff
        // ...
    }
}

var search = new Search();
search.ask( 'eminem' );

I get an error Object success has no method loadResult , which makes sense as the callback is part of an anonymous jQuery function.

But how to get my initial object instance ?

I've been trying with a var that = this; before the Ajax call, but I't won't works for the same reasons.

I don't know if it's possible to do this or if the problem comes from my code global organization. Feel free to advise me about the best practices :)

Thanks by advance.

[Update (solved)]

I obfuscated some things in my code which I though it was unnecessary to post here, but I finally found out the problem a little bit earlier in my code. Sorry about that.

Here's my full code, which is now working :

define(['jquery'], function($) {

    var Search = function()
    {
        this._keyDownTimer = 0;
        this._searchDelay = 1000; // ms
    };

    Search.prototype =
    {
        // The init function that I though it was unnecessary to post here. Sorry :/
        init : function()
        {
            $('#q').on('keydown', (function(evt) {

                clearTimeout( this._keyDownTimer );

                this._keyDownTimer = setTimeout( (function() {

                    this.ask( $('#q').val() );

                }).bind( this ), this._searchDelay); /* <-- Here's the solution.
                                                        I forgot to bind `this`
                                                        to the timeout callback function,
                                                        so the `this` under all of my code
                                                        was referring to the anonymous function
                                                        of this callback. */

            }).bind( this ));
        },

        ask : function( query )
        {
            // Display loader
            $('.loader').show();

            console.log(this); // Now `this` refers to my object :)

            var req = $.ajax({
                dataType : 'jsonp',
                type : 'GET',
                url : 'http://api.deezer.com/search/track/',
                context : this,
                data : {
                    output : 'jsonp',
                    q : query
                }
            });

            req.done(function(res) {
                this.loadResults(res);
            });
        },

        loadResults : function (res)
        {
            // Hide loader
            $('.loader').hide();

            // doing some stuff
            // ...
        }
    };

    return new Search;

});

Thanks for your replies, it really helped.

Pb solved.

like image 631
jmpp Avatar asked Oct 09 '13 14:10

jmpp


People also ask

What is callback method in AJAX?

Description. The ajaxSuccess( callback ) method attaches a function to be executed whenever an AJAX request completes successfully. This is an Ajax Event.

Which object can be used to retrieve data in AJAX?

XMLHTTPRequest object is an API which is used for fetching data from the server. XMLHTTPRequest is basically used in Ajax programming. It retrieve any type of data such as json, xml, text etc. It request for data in background and update the page without reloading page on client side.

How use this AJAX success?

"this" can be accessed inside jQuery AJAX success and error callbacks by setting the "context" configuration property for $. ajax() or changing context of AJAX callbacks using $. proxy() method. It is very common to access this inside jQuery AJAX's response callbacks (success or error).


1 Answers

There are several ways to do this.

You can set the context setting for the ajax options:

jQuery.ajax context setting

$.ajax({
    context: this

Function.prototype.bind

    .done(function (res) {

    }.bind(this));

However, this is not as widely supported as...

jQuery.proxy

Created for this purpose.

    .done($.proxy(function (res) {

    }, this);

Assigning this to another value

var self = this;
$.ajax({
/* snip */
.done(function (res) {
    self.loadResults(res);

This is commonly done in JavaScript to give access to this in lower scopes.

Arrow functions with lexical binding

$.ajax({
/* snip */
.then(res => this.loadResults(res));
like image 133
Explosion Pills Avatar answered Oct 15 '22 17:10

Explosion Pills