osmanraifgunes osmanraifgunes - 15 days ago 16
Node.js Question

Ecmascript 6 recursive function with promise

I am trying to write a base class for sequelize.js. This class will associate all related tables. includeFk function realize this task. But it has a promise and should be recursive.
Class :

class base {
constructor(table, depth) {
this._table = table;
this._depth = depth;

}

includeFK(table, depth, includes) {
return new Promise((resolve, reject) => {
if (depth <= this._depth) {
for (var att in table.tableAttributes) {

table.belongsTo(m, {
as: m.name,
foreignKey: att
})
includes.push({
model: m
});

}
}

Promise.all(

Object.keys(table.associations).forEach(tbl => {
this.includeFK(table.associations[tbl].target, depth + 1, includes);
}

)).then(results => {
resolve(true)
});
} else {
resolve(true);
}
});



all(query) {
return new Promise((resolve, reject) => {
var tmp = this;
var includes = [];

Promise.all([
this.includeFK(tmp._table, 1, includes),
this.includeLang()
]).then(function() {

tmp._table.findAll({
include: includes
}).then(function(dbStatus) {
resolve(dbStatus);
});
});
});
}
}


Error :


(node:25079) UnhandledPromiseRejectionWarning: Unhandled promise
rejection (rejection id: 3): TypeError: Cannot read property
'Symbol(Symbol.iterator)' of undefined (node:25079)
DeprecationWarning: Unhandled promise rejections are deprecated. In
the future, promise rejections that are not handled will terminate the
Node.js process with a non-zero exit code. (node:25079)
UnhandledPromiseRejectionWarning: Unhandled promise rejection
(rejection id: 4): TypeError: Cannot read property
'Symbol(Symbol.iterator)' of undefined

Answer

You have the handle the error from Promise.all because it also return a promise and you need to handle it unless you train it to the returned promise.

Promise.all([...])
    .then(...)
    .catch(function(err) {
        console.error(err);
        reject(err);
    });

Edit:

var promiseArr = [];

Object.keys(table.associations).forEach(tbl => {
  promiseArr.push(
    self.includeFK(table.associations[tbl].target, depth + 1, includes)
  );
});

Promise.all(promiseArr)
  .then(results => {
    resolve(true)
  });

I also think your this binding isn't in the correct scope. If you get error of undefined function, try to reference this with a variable before calling class functions.

Example:

includeFK(table, depth, includes) {
    var self = this; //ref this and use it later
  ...
      ...
           self.includeFK();