Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chaining waterline calls with Promises

I have been hitting my head off a wall on this for the last 3 days.

I am using sailsjs & the waterline ORM that comes bundled. I want to run DB calls one after an other. I know I can do this by nesting inside "then" calls but it just looks wrong.

I have gone over the Q documentation and tutorials several times but I still don't get how to connect and fire "then" calls from existing Promises sequentially :(

I want to:

  1. create a user
  2. create a action
  3. link the user & action
  4. update the user
  5. update the action

My code looks like

 var mail = '[email protected]';

 Users.create({email:mail, name:''}).then(console.log).fail(console.log);

 Actions.create({actionID:123})
 .then(function(error, action){
        Users.findOneByEmail(mail).then(function(person){
            person.actions.add(action.id);
            person.save(console.log);
        }).fail(console.log)  
     });

 Users.update({email:mail},{name:'Brian'}).exec(console.log);
 Actions.update({actionID:123},{now:'running'}).exec(console.log);

As you can see from the code I've been using a mix of exec & then :P

I think the way is to connect the Users.create(...).then -> Action.create(...).then -> Users.findOneByEmail(...).then -> *and the updates.

Huge thanks from any help

like image 659
codemeasandwich Avatar asked Oct 18 '14 09:10

codemeasandwich


1 Answers

So after a day's research. I think I've cracked it.

Note: The first version I got working had the "then"s lined-up(removing the pyramid of doom) by returning the create. This allow me to call then on the next line to fire the create. http://documentup.com/kriskowal/q/#tutorial/chaining

Here's my final version

var mail = '[email protected]';    

Users.Create({email:mail,name:''})
  .then(function(user){
    return [Actions.create({actionID:123}),user];
  }).spread(function(action, user){

     user.action.add(action.id);
     user.name = 'Brian';
     user.save();

     action.now = 'running';
     action.save();
  }).catch(console.error);

One of the cool things is the "spread" that allows you to line-up "Promises" and "values" to be return one they all have completed into the next "then".

like image 188
codemeasandwich Avatar answered Sep 30 '22 05:09

codemeasandwich