0

I have looked at the example posted here: YDN-DB with multiple deferred which contains some code that is very close to what I want, but not quite.

I am wondering if it is safe to nest deferred queries in a transaction? For example:

loadWorkOrders: function() {

        var params = {
            userId: 1,
            status: Status.Allocated
        };

        var allOrders = null;

        return workOrderHttpService.getWorkOrders(params).then(function(orders) {
            allOrders = orders.data;
            return ydndatabase.open();
        }).then(function(db){
                return db.run(function(runDb){
                    allOrders.forEach(function(workOrder){
                        runDb.count(Store.WorkOrder, ydn.db.KeyRange.only(workOrder.id)).then(function(count) {
                            if(count == 0) {
                                return runDb.put(Store.WorkOrder, workOrder);
                            } else {
                                return workOrder;
                            }
                        });
                    });
                }, [Store.WorkOrder], TransactionType.ReadWrite)
            });

    }

EDIT: I have edited the code to show how it is preceded by an async call to an http service

Community
  • 1
  • 1
gusgorman
  • 170
  • 1
  • 11
  • 1
    [Don't create a deferred](https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern) to tell when your `req` promise has resolved, you already have a promise!!! – Bergi May 15 '14 at 16:38
  • Ah good point yes thankyou. (This is still prototype code hacked together very quickly) However, the question still stands. – gusgorman May 15 '14 at 16:45

1 Answers1

1

Yes, you are using it right. As @Bergi said, you can just return the run request.

It is safe to nest deferred as long as your promises are resolved synchronously or using db promises (always asynchronous).

Nesting deferred is generally fine, looping is to be worry about, such as orders.forEach for unexpected large loop. Browsers are not happy with long transaction (yes, can cause mysterious error or crash).

Like the way using count to check for record existance. I think it should be ydn.db.KeyRange.only(workOrder.id), since count require a key range input argument.

Kyaw Tun
  • 12,447
  • 10
  • 56
  • 83
  • Many thanks for that..... but re: returning the run request i can't because I actually simplified the code in order to post it here. In the real code the service that returns the original list of orders returns a promise so the code above is wrapped in another then(). – gusgorman May 16 '14 at 12:36
  • This is OT but Just realised that I probably need to be chaining promises instead of nesting them. – gusgorman May 16 '14 at 12:50
  • No. looping will run faster. – Kyaw Tun May 16 '14 at 13:45
  • Sorry... actually the above code does not work. Doing ydn.db.KeyRange.only(workOrder.id) works but then each runDb.put gives out the following error: "Uncaught TransactionInactiveError: Failed to execute 'put' on 'IDBObjectStore': The transaction is not active." – gusgorman May 20 '14 at 09:20
  • I have edited the code to show how it is preceded by an async call to an http service. Should this make any difference? – gusgorman May 20 '14 at 10:40
  • what you show here is fine. You should not get any error. What is the size of orders? smaller size also cause error? – Kyaw Tun May 20 '14 at 11:09
  • At the moment I am only testing it with 10 orders. I have to admit I didn't expect it to work, thats why I asked the question in the first place. Seeing as all IndexedDB calls are async I don't understand how the transaction knows to stay open. I can see it might stay open long enough to register the "counts", but by the time the "puts" are executed why would it still be open? (I realise this is probably just a lack of knowledge on my part!) – gusgorman May 20 '14 at 11:19
  • Yes, transaction is still active. I see. Return statement on put is wrong. It is not necessary. – Kyaw Tun May 20 '14 at 11:57
  • I've just tried removing the return statement.. but same problem. – gusgorman May 20 '14 at 12:35
  • You mean the else { return workOrder; }? If so.. yes I have already removed that. – gusgorman May 20 '14 at 13:10
  • Yes. Should no problem now. – Kyaw Tun May 20 '14 at 13:26
  • I am starting to think there is an incorrect version of the library available for download. As well as the problem above I have 2 other problems: (1) The addEventListener('ready', fn) function does not exist. (2) I am getting the same var is not defined error when I use db.get(Store.WorkOrder,1) as mentioned in the comments here: http://stackoverflow.com/questions/19203164/ydn-db-how-to-verify-if-a-record-exists/19204459#19204459 – gusgorman May 20 '14 at 13:27