Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #26196

Javascript Promises not executing correctly

Newsgroups comp.lang.javascript
Date 2014-11-23 11:36 -0800
Message-ID <feb09963-ae4f-4675-afd8-24fe5fbfe831@googlegroups.com> (permalink)
Subject Javascript Promises not executing correctly
From José Luis Gallego <jlgallego@gmail.com>

Show all headers | View raw


Hello,

I have already asked for support on this issue on stackoverflow. You may see the long question here: 

http://stackoverflow.com/questions/26994436/javascript-promises-not-executing-correctly-two-objects-in-jquery-tmpl-using-e

I have a problem with promises (who doesn't). It looks like two deferred functions are messing up the timing and executing asynchronously although they look like they should execute synchronously. I'll expose the code here.


Function getTariffByProductItem:

getTariffByProductItem: function(productItemId) {
        // Return Array of tariffs
        var def = new $.Deferred();
        var tariffs = [];
        db.transaction(function(tx) {
            tx.executeSql('select pric.pric_cd_pricing, pric.pric_ds_pricing ' + 
                            'from tga_pricings pric ' +
                            'where date(\'now\') <= pric.pric_dt_valid_to ' +
                            'and date(\'now\') >= pric.pric_dt_valid_from ' +
                            'and pric.pric_cd_product_item = ?',
            [productItemId],
            function(tx,dbResult) {
                if(dbResult.rows.length) {
                    for(var i = 0; i < dbResult.rows.length; i++) {
                        tariffs.push( 
                            {
                                cdPricing: dbResult.rows.item(i).pric_cd_pricing,
                                dsPricing: dbResult.rows.item(i).pric_ds_pricing
                            }
                        );
                    }
                    def.resolve(tariffs);   
                }
            });
        }
        , function(e) { 
            alert("There has been an error: " + e.message); 
            def.reject();
        });

        return def.promise();
    }


Function editBookPaxBuyPrepare:

editBookPaxBuyPrepare: function(productId) {
    var def = new $.Deferred();
    var bookingId = $( '#edit-book-pax-pricing-form' ).data('bookid');
    var paxId = $( '#edit-book-pax-pricing-form' ).data('paxid');
    var productItems = [];

    // Check for actual data
    db.transaction(function(tx) {
        // Get product items for product
        tx.executeSql('select prit.prit_cd_item, prit.prit_st_name ' +
                        'from tga_products_catalog prod ' +
                        'inner join tga_product_items prit ' +
                        'on prit.prit_cd_product = prod.prod_cd_product ' +
                        'where prod.prod_cd_product = ?',
        [ productId ],
        function(tx, dbResult) {
            if(dbResult.rows.length) {
                // Set form action to EDIT
                $('#edit-book-pax-buy-form').data('formaction', 'edit');
                // Set product name label
                $('#edit-book-pax-buy-product').text(dbResult.rows.item(0).prod_ds_product);
                for(var i=0; i<dbResult.rows.length; i++) {
                    // For each producItem get tariffs
                    var dbRow = dbResult.rows.item(i);  
                    var data = [];

                    $.when(bookings.getTariffByProductItem(dbRow.prit_cd_item))
                    .then(function(data) {
                        console.log("Product Item: " + dbRow.prit_st_name + " - tariffsArray: " + JSON.stringify(data));
                        productItems.push({ "row": dbRow, "tariffs": data });
                    });
                }
                def.resolve(productItems);
            }   
        });

    },
    function(e) {
        def.reject(e);
    });
    return def.promise();
}


Main code calling both above functions:

var listFieldset = $( '#edit-book-pax-buy-form-product-items-list' );
listFieldset.empty();
$.when(bookings.editBookPaxBuyPrepare(productId))
.done(function(productItems) {
    console.log(JSON.stringify(productItems));
    $( "#edit-book-pax-buy-product-item" ).tmpl( productItems ).appendTo( listFieldset );
    listFieldset.trigger('create');
    listFieldset.listview('refresh');
});


The log I get:

bookings.js:738 []
2014-11-23 20:03:06.151bookings.js:566 Product Item: 1105 - Local guide - tariffsArray: [{"cdPricing":7,"dsPricing":"Operator tariff"}]
2014-11-23 20:03:06.155bookings.js:566 Product Item: 1105 - Local guide - tariffsArray: [{"cdPricing":14,"dsPricing":"Operator tariff"}]
2014-11-23 20:03:06.159bookings.js:566 Product Item: 1105 - Local guide - tariffsArray: [{"cdPricing":15,"dsPricing":"Operator tariff"}]
2014-11-23 20:03:06.163bookings.js:566 Product Item: 1105 - Local guide - tariffsArray: [{"cdPricing":16,"dsPricing":"Operator tariff"}]


As you can see, "console.log(JSON.stringify(productItems));" is executed BEFORE the console.log line in the loop inside editBookPaxBuyPrepare function. The expected behaviour is the other way round: wait until editBookPaxBuyPrepare finishes and then log the contents of the returndes array in the promise.

Any help is welcome!

Thanks.

Back to comp.lang.javascript | Previous | Next — Next in thread | Find similar | Unroll thread


Thread

Javascript Promises not executing correctly José Luis Gallego <jlgallego@gmail.com> - 2014-11-23 11:36 -0800
  Re: Javascript Promises not executing correctly Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2014-11-24 01:49 +0100

csiph-web