views:

325

answers:

2

I'm iterating through a set of json data which carries results of a few database tables. Amongst other data I have a RateTable ...erm... table, and a Resources table. The RateTable has a property name ResourceId which links to the Resources record.

So, I'm iterating through my RateTable and I need to reference my Resource record and use it by copying it into it's own variable. Here is what I have so far:

if (data)
    {
        var rs = data.Resources;

        $.each(data.RateTables, function(i,item){
            if (item.RateTableTypeId == 91)
            {
                var r = getresource(item.SupplierResourceId, rs)
                if (r)
                    customer_options += '<option value="' + r.ResourceId + '">' + r.Name + '<\/option>';
            }
            else if (item.RateTableTypeId == 92)
            {
                var r = getresource(item.CustomerResourceId, rs)
                if (r)
                    supplier_options += '<option value="' + r.ResourceId + '">' + r.Name + '<\/option>';
            }

        });

        $(".ddl-customer").html(customer_options);
        $(".ddl-supplier").html(supplier_options);
    }

    function getresource(id, items)
    {
        $.each(items, function(i,item){
            if (item.ResourceId == id)
                return $.extend(true, {}, item);
        });
    }

The problem I have is that getresource isn't returning a copy of my Resource item in the variable r. Why?

Sorry I can't post some of the json data, it's absolutely huge, which is why we are leaving the referencing to the client side to cut down on the data payload. I'm hoping there is enough to help someone see what I'm trying to do.

Lloyd

+2  A: 

The problem I have is that getresource isn't returning a copy of my Resource item in the variable r. Why?

getresource doesn't have a return statement. There is a return statement inside the anonymous function used by the $.each() call inside getresource. That return statement returns from the anonymous function and back into $.each(). $.each() interprets the returned value -- if there is one -- as a boolean indicating whether to continue iterating. But that value never gets passed back to getresource, which doesn't have a return statement to return it anyway.

See http://docs.jquery.com/Utilities/jQuery.each#objectcallback for details about $.each().

One possible fix is to use javascript's native for loop instead, e.g.

function getresource(id, items) {
    for (var i = 0; i < items.length; ++i) {
       var item = items[i];
       if (item.ResourceId == id) {
           return $.extend(true, {}, item);
       }
    }
}

Another option is to keep using $.each() but return from getresource, e.g.

function getresource(id, items) {
    var r = null;
    $.each(items, function(i, item){
        if (item.ResourceId == id) {
            r = $.extend(true, {}, item);
            return false; // end $.each() loop
        }
    });
    return r;
}
Oren Trutner
+1  A: 

I admit I'm still learning and I've never seen anyone return an $.extend from a function...

Oren is right about you needing to return a false if the value is not found, so I'll give him +1.

Additionally, I attempted to test your function using return $.extend(false, {}, items); and it appears that if (r) will always true because r is an object,

I'm guessing you are trying to return two variables from a function? Anyway the best way to return mutliple variables from a function would be to use something like this:

function getresource(id, items)
    {
        $.each(items, function(i,item){
            if (item.ResourceId == id)
                return [true, item];
        });
        return false;
    }

then r[0] contains the boolean and r[1] contains the item (if true)

fudgey