gremo
gremo

Reputation: 48899

Understanding closure and scope

For some reason (probably because i don't understand closures) function inResult always returns false and the loop is never executed. Of course i'm sure that result contains has the right properties.

    function hasId() {return $(this).prop('id');}
    function inResult(res) { return res.hasOwnProperty($(this).prop('id'));}

    $.ajax({
        url : opt.url,
        data : $.extend(true, opt.data, {ids: ids}),
        context : this, // A collection of elements
        type : 'POST',
        dataType : 'json',
        success : function(result) {

            // Filter elements with id and with a property in result named "id"
            this.filter(hasId).filter(inResult(result)).each(function() {
                console.log($(this).prop('id'));
            });

        }
    });

EDIT: working code solution (thanks to Šime Vidas for poiting me in the right direction):

// Use closures to change the context later
var hasId    = function() { return $(this).prop('id'); };
var inResult = function(res) { return res.hasOwnProperty($(this).prop('id')); };

$.ajax({
    url : opt.url,
    data : $.extend(true, opt.data, {ids: ids}),
    context : this, // A collection of elements
    type : 'POST',
    dataType : 'json',
    success : function(result) {

        // Filter elements with id and with a property in result named "id"
        var filtered = this.filter(function() {
            // Note the context switch and result parameter passing
            return hasId.call(this) && isBinded.call(this, result);
        });

        filtered.each(function() { console.log($(this).prop('id')); });

    }
});

Upvotes: 3

Views: 135

Answers (1)

Šime Vidas
Šime Vidas

Reputation: 185893

Try this:

this.filter( hasId ).filter( function () {
    return inResult( result );
}).each( function () {
    console.log( this.id );
});

In your code you have .filter(inResult(result)) which won't work because you're invoking inResult immediately and passing the result of that invocation (which is a Boolean value) to filter(), which doesn't work with Boolean values.


You could also do it like so:

var keys = Object.keys( result );

var filtered = this.filter( function () {
    return this.id && keys.indexOf( this.id ) > -1;
});

Object.keys( result ) returns an array of all own property names from result.

Upvotes: 2

Related Questions