0

**Made changes to example to correct a syntax error (all bold), thanks Luc DUZAN for the help. Changed c.target.result to the actual array used to hold the data 'objCollection' in the every last code example.

Problem: I would like to add an argument to a callback that already has parameters.

For this problem, I have functionality that calls a function, DataLayer.GetData, and executes a callback on completion. I pass this callback, LoadResults, with two existing parameter into the function DataLayer.GetData inside an enclosure. The callback function, LoadResults, correctly gets called from DataLayer.GetData and the parameters originally assigned in the calling functionality are correctly passed into LoadResults.

Is there a generic way or industry standard I can unpack the callback add the c.target.result argument and then call the callbackOnComplete callback so that c.target.result ends up as the dataResults argument in LoadResults?

Calling functionality:

var dbCallback = function () { LoadResults('530', material.Id); };
DataLayer.GetData('530', 'TypeIndex', dbCallback);

Data tier function:

DataLayer.GetData = function (indexKey, indexName, callbackOnComplete) {
    var _this = this;
    var objCollection = new Array();

    try {
        var trans = _this.transaction(['objectStoreName'], "readonly");
        var store = trans.objectStore('objectStoreName');
        var index = store.index(indexName);
        var request = index.openCursor(indexKey);
        request.onerror = function (e) {
            ...
        }
        request.onsuccess = function (e) {
            var cursor = e.target.result;
            if (cursor) {
                objCollection.push(cursor.value);
                cursor.continue();
            }
        }
        trans.oncomplete = function (c) {
            if (callbackOnComplete) callbackOnComplete();
            else ...
        }
    }
    catch (e) {
        ...
        return false;
    }
}

Callback function:

LoadResults = function(formType, materialCode, dataResults) {
   ...
}

What I would like to be able to accomplish within the DataLayer.GetData / trans.oncomplete event is add the argument objCollection to the callbackOnComplete callback list of arguments. Something like:

callbackOnComplete.arguments.push(objCollection);

Or is there another means of passing in a callback and its parameters?

Solution identified by Luc DUZAN: Calling functionality:

DataLayer.GetData.bind(null, '530', material.Id));

Data tier function:

DataLayer.GetData = function (indexKey, indexName, callbackOnComplete) {
    var _this = this;
    var objCollection = new Array();
    try {
        var trans = _this.transaction(['objectStoreName'], "readonly");
        var store = trans.objectStore('objectStoreName');
        var index = store.index(indexName);
        var request = index.openCursor(indexKey);
        request.onerror = function (e) {
            ...
        }
        request.onsuccess = function (e) {
            var cursor = e.target.result;
            if (cursor) {
                objCollection.push(cursor.value);
                cursor.continue();
            }
        }
        trans.oncomplete = function (c) {
            if (callbackOnComplete) callbackOnComplete.apply(null, [objCollection]);
            else ...
        }
    }
    catch (e) {
        ...
        return false;
    }
}

Callback function:

LoadResults = function(formType, materialCode, dataResults) {
   ...
}
indianapolymath
  • 323
  • 1
  • 4
  • 15
  • 1
    what's wrong with `callbackOnComplete()`? – The Reason Apr 11 '16 at 15:29
  • It's not `callbackOnComplete` parameters you want to augment, it's the call to `LoadResults()` *within* that function you want to change. Although this is a nice question, it's a sign of bad design and while possible, it won't be pretty. – haim770 Apr 11 '16 at 15:37

1 Answers1

1

In a first time, you should provide to GetData a callback that only require arguments from c.target.result.

It should not be the concern of your GetData to deal with callback that take others parameters. You can do that easily in ES5 with Function.prototype.bind:

DataLayer.GetData('530', 'TypeIndex', LoadResults.bind(null, '530', material.id));

Then in GetData, you only concern is too call your callback with value from c.target (which if I understood well is an array). For you can use Function.prototype.apply:

callbackOnComplete.apply(null, c.target);

For example if c.target is [1,2,3], this line will be equivalent to:

callbackOnComplete(1,2,3)
Luc DUZAN
  • 1,299
  • 10
  • 18