2

I am new in nodejs and mongodb. Its really very confusing to use promise in loop in nodejs for new developer.I require the final array or object. which then() give me final result. Please correct this.
I have a controller function described below.

let League = require('../../model/league.model');
let Leaguetype = require('../../model/leagueType.model');
let Leaguecategories = require('../../model/leagueCategories.model');


let fetchLeague = async function (req, res, next){
    let body = req.body;
    await mongo.findFromCollection(Leaguetype)
    .then(function(types) {
        return Promise.all(types.map(function(type){ 
            return mongo.findFromCollection(Leaguecategories, {"league_type_id": type._id})
            .then(function(categories) {
                return Promise.all(categories.map(function(category){
                    return mongo.findFromCollection(League, {"league_category_id": category._id})
                    .then(function(leagues) {
                        return Promise.all(leagues.map(function(league){
                            return league;
                    }))
                    .then(function(league){
                        console.log(league);
                    })
                    })
                }))
            });
        }))

    })
    .then(function(final){
      console.log(final);
    })
    .catch (error => {
      console.log('no',error);
  })
}

mongo.findFromCollection function is looking like this.

findFromCollection = (model_name, query_obj = {}) => {
        return new Promise((resolve, reject) => {
            if (model_name !== undefined && model_name !== '') {
                    model_name.find(query_obj, function (e, result) {

                    if (!e) {
                        resolve(result)
                    } else {
                        reject(e);
                    }
                })
            } else {
                reject({ status: 104, message: `Invalid search.` });
            }
        })
    }

and here is my model file

var mongoose = require('mongoose');
const league_categories = new mongoose.Schema({
        name: {
          type: String,
          required: true
        },
        active: {
          type: String,
          required: true
        },
        create_date: {
          type: Date,
          required: true,
          default: Date.now
        },
        league_type_id: {
          type: String,
          required: 'league_type',
          required:true
        }
      })

module.exports = mongoose.model('Leaguecategories', league_categories)

1 Answer 1

1

First i recommend you stop using callbacks wherever you can, its a bit dated and the code is much harder to read and maintain.

I re-wrote your code a little bit to look closer to what i'm used to, this does not mean this style is better, i just personally think its easier to understand what's going on.

async function fetchLeague(req, res, next) {
    try {
        //get types
        let types = await Leaguetype.find({});

        //iterate over all types.
        let results = await Promise.all(types.map(async (type) => {
            let categories = await Leaguecategories.find({"league_type_id": type._id});
            return Promise.all(categories.map(async (category) => {
                 return League.find({"league_category_id": category._id})
            }))
        }));

        // results is in the form of [ [ [ list of leagues] * per category ] * per type ]
       // if a certain category or type did not have matches it will be an empty array.
        return results;
    } catch (error) {
        console.log('no', error);
        return []
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your quick answer but when i am doing console.log(types) its giving me correct result but inside Promise if I console.log(type) nothing happen. It means type._id not getting. please look into this.
This is mb, i'm using bluebird promises instead of native promises. and i just wrote it as bluebird.map, i have edited my answer to match the native js promise.
thanks a lot! You saved my time. One more thing i want to know that for big application should i have to ignore callbacks function.
make sure that the number of records from leagueType collection aren't too many else you will be opening lots of parallel promises which might end up failing. best is to batch them if you can. something like https://www.npmjs.com/package/batch-promises
@tomslabbaert if i want to make some array after league.find than how to return that particular array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.