I'm using bluebird in NodeJS. I want to do a nested loop. Something like this:
var Promise = require('bluebird');
funcs.getLatestVideos = function(job, done) {
return Promise.try(function() {
return ProcessRules.getLatestVideos();
})
.then(function(object) {
return ({
'series': ProcessRules.getSeriesRules(),
'videos': object.videos
});
})
.then(function(inputs) {
return Promise.map(inputs.videos, function(video) {
return Promise.map(inputs.series, function(series) {
return Promise.map(series.rules, function(rule) {
return ProcessRules.processRules(video, rule);
});
});
})
})
.then(function(result) {
W.debug("done");
console.log(JSON.stringify(result));
done();
})
.catch(function(err) {
done(err);
W.error("Error occurred ", err.message, err.stack);
});
}
ProcessRules
var Promise = require('bluebird');
var rp = require('request-promise');
var W = require('winston');
var RuleEngine = require('node-rules');
var _ = require('lodash');
funcs.getSeriesRules = function() {
return new Promise(function(resolve, reject) {
var options = {
method: "GET",
uri: API_URL,
// body: status,
json: true // Automatically stringifies the body to JSON
};
rp(options)
.then(function(result) {
resolve(result)
})
.catch(function(err) {
reject(err)
});
});
};
funcs.processRules = function(fact, rule) {
return new Promise(function(resolve, reject) {
var rules = [];
var value = new RegExp(rule.value, 'i');
switch (rule.type) {
case 'title':
rules = [{
"condition": function(R) {
// console.log(this.title.match(value));
R.when(this.title.match(value) > -1);
},
"consequence": function(R) {
this.result = false;
this.video = R;
R.stop();
}
}];
break;
case 'desc':
rules = [{
"condition": function(R) {
//console.log(this.desc.match(value));
R.when(this.desc.match(value) > -1);
},
"consequence": function(R) {
this.result = false;
this.video = R;
R.stop();
}
}];
break;
case 'tag':
rules = [{
"condition": function(R) {
// console.log(this.tag.match(value));
R.when(!_.some(this.tags, { 'text': rule.value}))
},
"consequence": function(R) {
this.result = false;
this.video = R;
R.stop();
}
}];
break;
default:
break
};
//initialize the rule engine
const R = new RuleEngine(rules);
//Now pass the fact on to the rule engine for results
R.execute(fact, function(result) {
//console.log(result);
if (result.result) {
resolve(result._id)
}else{
resolve({})
}
});
});
};
It returns me following output
[[[{},{},"58e9d6816961c30367b5154c"],[{}],[],[],[]],[[{},{},"58e9d6816961c30367b5154d"],[{}],[],[],[]]]
But I am expecting with following output:
[58e9d6816961c30367b5154c,58e9d6816961c30367b5154d]
I see some similar question but not getting exact ideas from them.
In getLatestVideos
function not able to get done result ,Please help me to resolve this issue.
Please help me to implement nested each loop with bluebird promise.
After long search with multiple questions and answers , I got the answer by Flattening a Promise map.
I don't know exactly its right way but its working for me.
.then(function(inputs) {
return Promise.map(inputs.videos, function(video) {
return Promise.map(inputs.series, function(series) {
return Promise.map(series.rules, function(rule) {
return ProcessRules.processRules(video, rule);
}).reduce(function(prev, cur) {
return cur ? prev.concat(cur) : [];
}, [])
}).reduce(function(prev, cur) {
return prev.concat(cur);
}, [])
}).reduce(function(prev, cur) {
return prev.concat(cur);
}, [])
})
It returns me [58e9d6816961c30367b5154c,58e9d6816961c30367b5154d]
.
Thanks Everyone.