1

new to stackoverflow/nodejs/mongo/promises/es6. I have succesfully created some simple queries and inserts, using promises, but am now up against a wall, so thought I would ask for some help.

I am trying to retrieve a list of Routines with a lookup to a creator (owner) and a (workout) name to pick out a Workout, related (1to1) to Routine.

I've tried with ideas here Aren't promises just callbacks? and How to chain and share prior results with Promises but just can't seem to get a loop to work with the flat chaining idea.

So, in pseudo code

getRoutineList
foreach routine:
    get user account using Routine.email
    get workout for Routine, using user._id and Routine.workout_name
    return the list of routines and workouts

My initial idea based on what I currently have working and my limited experience.

var rp = routines.find( {owner : user_id}).toArray().then( function( routine_list){
    for( var i =0; i<routine_list.length; i++){
        var routine = routine_list[i];
        var ap = accounts.find( {email:routine.creator}).toArray().then( function( creator){
            var workout_owner = creator[0];
            var creator_id = workout_owner._id.toHexString(); // .toString();

            var wp = workouts.find( { owner : creator_id, name : routine.ofWorkout})
                                .toArray().then( function( workout_list ){
                return workout_list;
            });
            that.promises.push( wp);
            console.log( "add workout promise count:", that.promises.length);
        });
        that.promises.push(ap);
        console.log( "add account promise count:", that.promises.length);
    }
    return routine_list;
});
that.promises.push( rp);
console.log( "add routine promise count:", that.promises.length);


Promise.all( that.promises).then( function( promise_results){
    console.log( "promises count:", that.promises.length);
    console.log( "promises complete, data:", promise_results);

    var data = {};
    data["routines"] = promise_results[0];
    var workouts = [];
    for( var i = 1; i<promise_results.length; i++){
        workouts.push( promise_results[i]);
    }
    data["workouts"] = workouts;

    res.status(200).send( [promise_results]);
});

try an edit here - this question is about promise chaining, not closures within loops - JavaScript closure inside loops – simple practical example. I'm now hoping for advice about my solution.

Community
  • 1
  • 1
nikrb
  • 153
  • 3
  • 10
  • Try using `let` instead of `var`. – jib Mar 27 '16 at 00:44
  • Possible duplicate of [JavaScript closure inside loops – simple practical example](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – jib Mar 27 '16 at 01:02
  • I wasn't aware of let, I'll give it a go. I don't really see any correlation to possible duplicate, but I have little experience so what do I know - but thanx for your comments. I tried the edit box up top, but the explanation doesn't seem to appear anywhere, so writing here - new to SO aswell. – nikrb Mar 28 '16 at 00:52

1 Answers1

1

there's something about organising thoughts and cutdown code for posting in a forum ... I've managed to solve the problem, atleast I have something that works. It doesn't 'look' right to me and certainly isn't flat, so please if you know a better/proper way, speak up, thanx.

var rp = new Promise( function( resolve, reject){
    routines.find( {owner : user_id}).toArray()
    .then( function( results){
        results.forEach( function( obj, ndx, arr){
            accounts.find( {email:obj.creator}).next( function( e, acc){
                // obj.creator_account = acc;
                obj.creator_id = acc._id.toHexString();
                workouts.find( { owner : obj.creator_id, name : obj.ofWorkout}).next( function( e, workout){
                    console.log( "got workout:", workout);
                    obj.workout = workout;
                    if( ndx === arr.length-1) resolve( results);
                });
            });
        });
    });
}).then( function( results){
    console.log( "results:", results);
    res.status(200).send( results);
});
nikrb
  • 153
  • 3
  • 10