pusher / chatkit-server-node

Node.js SDK for Pusher Chatkit
https://pusher.com/chatkit
MIT License
16 stars 9 forks source link

Async / Promise behavior is unpredictable for basic queries #39

Closed dcsan closed 5 years ago

dcsan commented 5 years ago

What?

I'm using the nodeJS lib, and having problems with promises not seeming to resolve when using async/await syntax


    let userRooms = await Rabbit.chatkit.getUserRooms({
      id: userId
    })
    debug.info('userRooms=>', userRooms) // [] empty

    let p = Rabbit.chatkit.getUserRooms({
      id: userId
    })
    debug.info('getUserRooms result=>', p) // Promise { <pending> } 
    p.then( info => {
      debug.info('p.then info', info) // [ ] still empty!
    })

    Rabbit.chatkit.getUserRooms({
      userId: userId
    }).then( (res, err) => {
      debug.info('userRooms p.res', res) // the only way this code works...
    })

only the final method will work

  Rabbit userRooms=> [] +302ms
  Rabbit getUserRooms result=> Promise { <pending> } +1ms
  Rabbit p.then info [] +309ms

  Rabbit userRooms p.res [ { created_at: '2019-01-28T06:31:30Z',
    created_by_id: 'dcsan',
    id: '19398582',
    member_user_ids: [ 'adminBot', 'dcsan', 'genie' ],
    name: 'lobby',
    private: false,
    updated_at: '2019-01-28T06:31:30Z' },
  { created_at: '2019-02-15T07:13:27Z',
    created_by_id: 'genie',
    id: '19408194',
    member_user_ids: [ 'dcsan', 'genie' ],
    name: 'testing',
    private: false,
    updated_at: '2019-02-15T07:13:27Z' },
  { created_at: '2019-02-15T07:17:03Z',
    created_by_id: 'genie',
    id: '19408196',
    member_user_ids: [ 'dcsan', 'genie' ],
    name: 'empty',
    private: false,
    updated_at: '2019-02-15T07:17:03Z' } ] +9ms

Suggested improvements

I am getting an empty array [] as the result so it is not undefined ... but the array hasn't been populated before the Promise resolves, it seems, when using anything other than an inline .then()

Is there a way to get more expected behavior? According to the node docs, each function should return a Promise, but even using p.then I can't get quite what I'm expecting. Perhaps this is related to the Promise itself being resolved, but the data isn't ready internally inside somehow from the socket? Really not clear

dcsan commented 5 years ago

https://docs.pusher.com/chatkit/reference/server-node#sdk-usage

in specific I'm not sure why I get different behavior for

   let p = Rabbit.chatkit.getUserRooms({
      id: userId
    })
    p.then( info => {
      debug.info('p.then info', info) // empty array []
    })

vs doing it all on one line

    Rabbit.chatkit.getUserRooms({
      userId: userId
    }).then( (res, err) => {
      debug.info('userRooms p.res', res) // finally found a magic incantation
    })

the returned intermediate object IS a promise so...

So I guess there's some magic going on and I just have to be really careful and write old style callback functions to work with the Pusher node API?

callum-oakley commented 5 years ago

@dcsan I can understand your confusion, because all three of the above should indeed be equivalent!

In fact on closer inspection the problem has nothing to do with how you're waiting for the promise... but with a typo in the parameters. The ones which don't work have id: userId, and the ones which do have userId: userId.

We should probably add runtime type checks to avoid errors like this, but in the first two cases you are looking for rooms which the user with ID undefined is in... which is why you get back an empty list...

Sorry for the delay replying here, the issues on this SDK have been slipping through the net somewhat. Our bad.