Rahul Sharma Rahul Sharma - 4 months ago 20
Javascript Question

Pubnub: cannot get state object with presence event

I am trying to get data (state) object in the presence event as documented in Pubnub Documentation.

Here's my code :-

// Subscribe to messages channel
Pubnub.subscribe({
channel: $scope.channel,
triggerEvents: ['callback','presence','message'],
state: {
username : $scope.username,
membershipType : $scope.membershipType,
memberDealsIn : $scope.memberDealsIn
}
});

//Track online users
Pubnub.here_now({
channel : $scope.channel,
state: true,
callback : function(m){
$scope.$apply(function() {

$scope.onlineUsers.push(m['uuids'])
});
}
});

//User's State
Pubnub.state({
channel : $scope.channel,
state : {
username : $scope.username,
membershipType : $scope.membershipType,
memberDealsIn : $scope.memberDealsIn
},
callback : function(m){
//console.log(m)
},
error : function(m){
//console.log(m)
}
});


I am calling it from the Pubnub's getPresenceEventNameFor method as :-

$scope.$on(Pubnub.getPresenceEventNameFor($scope.channel), function (ngEvent, pnEvent) {
console.log("pnEvent: ", pnEvent);
}


Here's my output :-

pnEvent: Object {action: "join", uuid: "1310974", timestamp: 1467719168, occupancy: 3}


As you can see everything else is just fine but I cannot get data in it.
Whereas the Documentation says it should have data too, like :-

{
"action" : "join",
"timestamp" : 1345546797,
"uuid" : "175c2c67-b2a9-470d-8f4b-1db94f90e39e",
"occupancy" : 2,
"data" : {
"age" : 67,
"full" : "RobertPlant",
"country" : "UK",
"appstate" : "foreground",
"latlong" : "51.5072°N,0.1275°W"
}
}


I have been stuck with this thing for a while now. :(

Please tell me what I am doing wrong here. Why isn't the state being set in the presence event.

Thanks for your help.

Answer

Finally. I have been able to detect the issue, thanks to pubnub support. It was due to the wrong timing of events. In my code, the here_now event was being triggered before the presence event for the user where its state is being set.

Now I am setting the state in the user's own join event and calling the here_now event in the state-change event. And its working.

    //Presence Callback
$scope.$on(Pubnub.getPresenceEventNameFor($scope.channel), function (ngEvent, pnEvent, envelope, channel) {

    //Detect Join events for users
    if (pnEvent['action'] === 'join') {

        //Detect User's own join event and set state for the user
        if (pnEvent['uuid'] === $scope.uuid) {
            //User's State
            Pubnub.state({
                channel  : $scope.channel,
                state    : {
                    username : $scope.username,
                    membershipType : $scope.membershipType,
                    memberDealsIn : $scope.memberDealsIn
                },
                callback : function(m){
                    //console.log(m)
                },
                error    : function(m){
                    //console.log(m)
                }
            });   
        }
    }

    //Detect state change event
    if (pnEvent['action'] === 'state-change') {

        //Call here_now on state change of a user
        //Track online users
        Pubnub.here_now({
            channel : $scope.channel,
            state: true,
            callback : function(m){
                $scope.$apply(function() {

                    for (var userIdx in m['uuids']) {
                        var user = m['uuids'][userIdx];

                        //Push new user to online User's list if not there
                        if (!_.find($scope.onlineUsers, {uuid: user.uuid}) && (user.uuid != $scope.uuid)){

                            //Push only if state is not undefined
                            if (user.state.membershipType != null) {
                                $scope.onlineUsers.push({uuid: user.uuid, membership: user.state.membershipType, dealsin: user.state.memberDealsIn, username: user.state.username});
                            }
                        }
                    }
                });
            }
        });
    }