2

I have component in react native that shows all the chats a user has. The main logic must be in componentDidMount(). Here, a simplified version:

componentDidMount(){
     ConnectyCube.chat.list({}, function(error, dialogs) {
        chats = dialogs.map(chat => {
            const opponentId = //some logic
            ConnectyCube.users.get(function(error, res){
                //some logic to populate chats 
            });
            }
        )

        this.setState({chats: chats})
        }
    );
}

Main problem, in other words, is that I don't know how to use multiple callbacks (one for each chat that the user has) to handle the data structure 'chats' in order to setState at the end. Maybe, my problem, is that I'm thinking in a synchronous way because I'm new to an event-driven approach. Any help is appreciated.

  • 1
    You may want to look into promises for this – Sterling Archer Feb 22 '19 at 21:12
  • 1
    Exactly, perhaps `Promise.all` – Andrew Feb 22 '19 at 21:12
  • The "manual way" is to keep track of how many responses have completed, and when that value is equal to the number of items in the array you trigger some "final callback" – James Feb 22 '19 at 21:13
  • ConnectyCube is an API that does not provide promises, but only callbacks. – Michele Papale Feb 22 '19 at 21:28
  • @James how can I keep track how many responses havee completed? – Michele Papale Feb 22 '19 at 21:30
  • You could wrap your `ConnectyCube.users.get` call in a promise that resolves when the callback comes back with the value you need and rejects when there is an error. See [3. Node style callback ("nodeback")](https://stackoverflow.com/a/22519785/5508175) then you could use a `Promise.all` to execute them all. – Andrew Feb 22 '19 at 21:37

1 Answers1

1

Here's a way you can keep track of the number of remaining requests and trigger some code when they are all complete. Note, this is almost exactly what Promise.all does.

//some kind of global or component level variable, tracks the number of pending requests left
var remaining = 0;

componentDidMount(){
     ConnectyCube.chat.list({}, function(error, dialogs) {
        // set remaining to how many dialogs there are
        remaining = dialogs.length;
        chats = dialogs.map(chat => {
            const opponentId = //some logic
            ConnectyCube.users.get(function(error, res){
                //some logic to populate chats

                // decrement remaining and check if we're done
                if (--remaining === 0) {
                  finalCallback(); // in here you do your setState.
                }
            });
            }
        )

        this.setState({chats: chats})
        }
    );
}
James
  • 20,957
  • 5
  • 26
  • 41