Question

I have been adapting the IBM angularjs tutorial here into a Yeoman angular-fullstack tutorial and it has been relatively easy except I have one Issue. When I vote on a Poll the data does not refresh and show the results on my version.

I have tried Debugging through it as best I can and I cannot see any difference between my version and the IBM version that would cause this issue. I have also looked here on SO and on google but I'm actually completely lost.

my entire code base is located here on github and I have embeded what I think is the relevant code below, Any help would be greatly appreciated

This is the client side controller

    .controller('PollViewCtrl', function ($scope, $routeParams, Poll, socket){
        $scope.poll = Poll.get({pollId: $routeParams.id});
        socket.on('myvote', function(data) {
                console.dir(data);
                if(data._id === $routeParams.pollId) {
                  $scope.poll = data;
                }
              });
              socket.on('vote', function(data) {
                console.dir(data);
                if(data._id === $routeParams.pollId) {
                  $scope.poll.choices = data.choices;
                  $scope.poll.totalVotes = data.totalVotes;
                }
              });
              $scope.vote = function() {
                var pollId = $scope.poll._id,
                    choiceId = $scope.poll.userVote;
                if(choiceId) {
                  var voteObj = { poll_id: pollId, choice: choiceId };
                  socket.emit('send:vote', voteObj);
                } else {
                  alert('You must select an option to vote for');
                }
              };
      })

and this is the relavent server side code

//app.js
var io = require('socket.io').listen(app.listen(config.port));
var poll = require('./lib/controllers/polls');
io.sockets.on('connection', poll.vote);

//poll.js
exports.vote = function(socket) {
  socket.on('send:vote', function(data) {
    var ip = socket.handshake.headers['x-forwarded-for'] || socket.handshake.address.address;
    Poll.findById(data.poll_id, function(err, poll) {
      var choice = poll.choices.id(data.choice);
      choice.votes.push({ ip: ip });
      poll.save(function(err, doc) {
        var theDoc = {
          question: doc.question, _id: doc._id, choices: doc.choices,
          userVoted: false, totalVotes: 0
        };
        for(var i = 0, ln = doc.choices.length; i < ln; i++) {
          var choice = doc.choices[i];
          for(var j = 0, jLn = choice.votes.length; j < jLn; j++) {
            var vote = choice.votes[j];
            theDoc.totalVotes++;
            theDoc.ip = ip;
            if(vote.ip === ip) {
              theDoc.userVoted = true;
              theDoc.userChoice = { _id: choice._id, text: choice.text };
            }
          }
        }
        socket.emit('myvote', theDoc);
        socket.broadcast.emit('vote', theDoc);
      });
    });
  });
};

Update

Here is the factory for socket

.factory('socket', function($rootScope) {
        var socket = io.connect();
        return {
          on: function (eventName, callback) {
            socket.on(eventName, function () {
              var args = arguments;
              $rootScope.$apply(function () {
                callback.apply(socket, args);
              });
            });
          },
          emit: function (eventName, data, callback) {
            socket.emit(eventName, data, function () {
              var args = arguments;
              $rootScope.$apply(function () {
                if (callback) {
                  callback.apply(socket, args);
                }
              });
            })
          }
        };
      });;
Was it helpful?

Solution 2

This was simply a mix up of variable name, while IBM was using pollId in their route for getting a poll I was using id but had managed to use pollId in my controller, once I changed this all behaved as expected.

OTHER TIPS

You have to make an apply when you're receiving the sockent on AngularJS because socket.io is not "in the AngularJS world".

You have a rerally great tutorial here to do what you want : http://www.html5rocks.com/en/tutorials/frameworks/angular-websockets/?redirect_from_locale=fr

If you have any questions just ask it !

Hope it helps

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top