3

A bit new to javascript. Been dealing with promises, however ran into a problem i dont know how to approach.

How can i pass a value into the next promise resolve?

Here's my code

bot.on('ask.add_account_password', (msg) => {
    let username = users[msg.from.id].username;
    let password = msg.text;
    var accounts = require('./inc/account.js');
    accounts.login_account(username,password).then(function(data){
        var account = data.params;
        console.log(account);
        return accounts.store(msg.from.id,username,password,account.followerCount);
    }).then(function(data){
        let caption = "Your account "+account.username+"("+account.fullName+")has been added\n";
        return bot.sendPhoto(msg.from.id, account.picture, {caption:caption});
    })
    .catch(function(error){
        console.log(error);
        add_account(msg,error.name);
    });
});

On the line where i create the caption variable, i'm trying to access the account object created in the block before it(var account = data.params) but i get a reference error saying its not defined. Now i can easily bypass this by just sending the entire object into the accounts.store function and have it resolve the object when done, but that just seems like a dirty workaround to a bigger problem. Is there a cleaner way to do this?

Haider Ali
  • 918
  • 2
  • 9
  • 26

3 Answers3

1

account is undefined at second .then(), use data to reference the Promise value accounts.store returned from previous .then()

.then(function(data) {
  // `data` : `accounts.store` returned from previous `.then()`
  let caption = "Your account " + data.username 
                + "(" + data.fullName + ")has been added\n";
  return bot.sendPhoto(msg.from.id, data.picture, {caption:caption});
})
guest271314
  • 1
  • 15
  • 104
  • 177
  • What makes you think that `store` returns a (promise for) the `account`? – Bergi Jul 30 '17 at 17:41
  • @Bergi _"What makes you think that store returns a (promise for) the account"_ Not sure what you mean? The gist of the Answer is that if OP needs to access a value from the previous `.then()` the returned value from previous `.then()` is the parameter at subsequent `.then()`. OP needs to make sure they are returning the correct value that they are expecting at subsequent `.then()` – guest271314 Jul 30 '17 at 17:49
  • Yes, but they `return accounts.store(…)` not `account` so this doesn't work that easily. – Bergi Jul 30 '17 at 17:51
  • @Bergi It was not immediately clear from OP exactly which object OP was expecting to return from previous `.then()`, nor exactly which object properties were expected at chained `.then()`. We had not gotten that far as to precisely what OP was returning or expecting at chained `.then()`. Not sure how your canonical can assist in that particular matter? Though OP will be able to review different possible patterns of accessing `Promise` values. – guest271314 Jul 30 '17 at 17:57
1

You can create variable (and set it in promise) in main function or you can return this as result of first promise instead of result from function store

hsd
  • 452
  • 5
  • 12
0

You can pass it in an array and use destructuring in the arguments to unpack the array.

accounts.login_account(username,password).then(function(data){
    var account = data.params;
    console.log(account);
    return [account, accounts.store(msg.from.id,username,password,account.followerCount)];
}).then(function([account, data]){
    let caption = "Your account "+account.username+"("+account.fullName+")has been added\n";
    return bot.sendPhoto(msg.from.id, account.picture, {caption:caption});
})

You don't actually appear to be using data, so you could just return account after calling store

the8472
  • 40,999
  • 5
  • 70
  • 122
  • The first propose solution is dangerous in context of promises. When function `store` return promise then chain of promises will be broken. – hsd Jul 30 '17 at 17:40
  • You would need to use `Promise.all` to make sure all promises in the array get awaited – Bergi Jul 30 '17 at 17:42