1

Alright, so this question is an extension of this question and related to this question. My code calling the function format can be seen in the first question. This is the code in my transform:

format() {
    return new Promise((resolve, reject) => {
        return Database.getInstance().getModel('feature_default').findAll({})
        .then((databaseObjects) => {
            this.getJsonObject().features = {};
            for (let databaseObject of databaseObjects) {
                console.log('ADD FEATURE DEFAULT TO ARRAY ' + databaseObject.id);
                this.getJsonObject().features[databaseObject.id] = JSON.parse(databaseObject.default_json);
            }
            console.log('RESOLVE FEATURE DEFAULT');
            return resolve(this.getJsonObject());
        })
        .catch((e) => {
            return reject(e);
        });
    });
}

I tried to remove the anti-pattern and I'm seeing the exact same behavior:

format() {
    return Database.getInstance().getModel('feature_default').findAll({})
        .then((databaseObjects) => {
            this.getJsonObject().features = {};
            for (let databaseObject of databaseObjects) {
                console.log('ADD FEATURE DEFAULT TO ARRAY ' + databaseObject.id);
                this.getJsonObject().features[databaseObject.id] = JSON.parse(databaseObject.default_json);
            }
            console.log('RESOLVE FEATURE DEFAULT');
            return this.getJsonObject();
        })
        .catch((e) => {
            throw e;
        });
}

Here is the code calling format:

            var promises = databaseObjects.map(databaseObject => {
                var jsonObject = {};

                var transform = new Transform();
                transform.setDatabaseObject(databaseObject);
                transform.setJsonObject(jsonObject);

                transform.baseFormat()
                .then(() => transform.format())
                .then(() => {
                    res.locals.retval.addData(jsonObject);
                    res.locals.retval.addErrors(transform.getErrors());
                    res.locals.retval.addWarnings(transform.getWarnings());
                }).catch((e) => {
                    console.log('Caught error during format of existing object: ');
                    console.log(e);
                    this.error(e, res);
                    throw e;
                });
            });
            Promise.all(promises)
            // ...

I've tried to do a Promise.all like in my second question, where each promise adds a feature to the array, but that did not fix this issue either.

Using this call, when I first query the server, I get the correct result:

{
  "errors": [],
  "warnings": [],
  "data": [
    {
      "id": 1,
      "name": "All",
      "enabled": 1,
      "features": {
        ...
      }
    }
  ]
}

However, on any subsequent calls I receive this:

{
  "errors": [],
  "warnings": [],
  "data": []
}

I am not changing any parameters or the call at all. I believe I'm failing to lock a Promise but I don't see where as I'm returning everywhere I should.

NobleUplift
  • 5,631
  • 8
  • 45
  • 87
  • 2
    https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it – Benjamin Gruenbaum Jan 05 '18 at 18:34
  • Déjà vu, I've just been in this place before. I should have bookmarked this question since I remember seeing it beforehand. Time to bookmark now. – NobleUplift Jan 05 '18 at 18:48
  • 1
    https://paste.ubuntu.com/26327304/ First of all, no need to write your promise related code without async/await and with explicit `return`s like we're in 2015 :D – Benjamin Gruenbaum Jan 05 '18 at 18:52
  • @BenjaminGruenbaum Sadly I don't think I can convert to async functions since format is being called by a Promise chain built up in the parent Transform class. You can see the code in [this answer](https://stackoverflow.com/a/44443791/904344). – NobleUplift Jan 05 '18 at 22:20
  • Also, I removed the anti-pattern from my code and I'm still seeing this occur. Maybe it's based on code further up in the chain. – NobleUplift Jan 05 '18 at 23:25
  • 1
    Looks to me like the issue is your `map` isn't returning the promise so `Promise.all` won't wait on anything. – James Jan 06 '18 at 00:16
  • 1
    I think you need to re write `transform.baseFormat()` and `transform.format()` to take a parameter and return the result (do not mutate parameter(s) passed in), because there is no guarantee of the order these transforms will happen. You can then use the results to mutate some "magic" `this` value after the Promise.all – HMR Jan 06 '18 at 04:37
  • @HMR To take databaseObject and jsonObject as parameters? I tried that before in my original code that can be seen [here](https://stackoverflow.com/q/44443563/904344), but the problem was that in the `extract` (saving) code, it wouldn't retain references to the two objects and they'd be undefined when it tried to save. – NobleUplift Jan 08 '18 at 15:44
  • @NobleUplift suspected that would be the culprit, however, as per lots of "example code" people make typo's etc. so didn't want to post an answer until you had clarified. Not sure if you can close as a duplicate (I can vote for it but would need other votes), if not then I suggest you just delete. – James Jan 08 '18 at 15:49
  • Yes. I fixed the same error in 2/4 places after that question, but forgot to update the other 2. My code is working now. – NobleUplift Jan 08 '18 at 16:12

0 Answers0