1

hello guys i'm trying to implement Upvote feature but i'm having some difficulties to get it toggle, by toggle i mean when user click the button/link it will perform upvote if the user click it again it will remove the upvote, just like a toggle button but i can't seem to find any relevant info from google. this is what i have so far

UPDATED

 $scope.up = function(){
   if(s_session != null){ // check user is logged in or not 
    data.getUserData().success(function(userData){ // get user data
        $scope.a = data1.votes.up; // this is the data from database
                            // is a list of username that who voted this post
     $scope.b = userData.publicUsername.display;// this is the current username                                    
     if($scope.a.indexOf($scope.b) == -1){ //check this username whether is in 
                                           // the list if -1 mean not
       $scope.user ={};
       $scope.user = userData;
       $scope.user.permalink = $routeParams.permalink;
       $http.post('/contentHandler/post/vote/up',$scope.user). // perform upvote                                                   
                    success(function(updatedData) {
                        $scope.votedMsg="VOTED";
                        $scope.afterVoteUp={'color':'#B3B3B3'}
                    }).error(function(err){

                    });  
              }else{ //else remove upvote
                $scope.user ={};
                $scope.user = userData;
                $scope.user.permalink = $routeParams.permalink;
                $scope.votedMsg="";
                $scope.afterVoteUp={'color':'#2ecc71'}
                $http.post('/contentHandler/post/vote/up/remove',$scope.user).
                    success(function(Data) {

                    }).error(function(err){

                    });
              }

        });
        }else{
          $location.path('/login'); //redirect to login if not logged in 
        }
      }

but problem is i can't click the button twice, the first click will perform upvote but the second click still will perform upvote, the problem is because the list of username is not being updated, but if i refresh the page and click it again it will remove the upvote. may i is there any better way to do this ?

1
  • Use a flag variable. like $scope.clicked = !$scope.clicked; if($scope.clicked){//dosomething} Commented Mar 5, 2014 at 12:34

3 Answers 3

2

A simple approach would be to maintain the state in a variable, but please read below for caveats

$scope.upVoted = false
$scope.up = function() { //ng-click
    if ($scope.upVoted) {
        $http.post('/contentHandler/post/vote/up', $scope.user).
        success(function(updatedData) {
            $scope.votedMsg = "VOTED";
            $scope.afterVoteUp = {
                'color': '#B3B3B3'
            }
        }).error(function(err) {

        });
    }else{
        $http.post('/contentHandler/post/vote/up/remove', $scope.user).
        success(function(updatedData) {
            $scope.votedMsg = "VOTE REMOVED";
            $scope.afterVoteUp = {
                'color': '#FFFFFF'
            }
        }).error(function(err) {

        });
    }
});

The potential issue you have with this and all frontend approaches is that the user can trivially change the value of upVoted, and vote again.

Assuming you're doing some validation in /contentHandler/post/vote/up you could alter it to toggle the vote on the server. That way the response could be the updated voted status from the server.

If you manage the state on the frontend, how will you know if the user has voted when they refresh the page?

Sign up to request clarification or add additional context in comments.

1 Comment

i have updated my question, sorry for my poor explanation and didn't state my question clearly
1

A clean approach would be:

<div ng-click="isUpVoted = !isUpVoted">{{isUpVoted}}</div>

JS:

$scope.isUpVoted = false;

$scope.$watch("isUpVoted",function(newVal, oldVal){
    if(newVal != oldVal){
        if(newVal){
            // perform upvote
        }
        else{
            // perform remove upvote
        }
    }
});

Fiddle

3 Comments

The ng-click="a =!a and watch is by far the cleanest way to achieve toggling. Nice answer :). I'm not a fan of adding the toggling logic to my HTML, so often add a toggleUpVote function to the $scope which does the same thing.
i have updated my question, sorry for my poor explanation and didn't state my question clearly
@JohnLim my answer still holds true.
1

I don't know AngularJS, but basic programming knowledge and assuming .up is the click handler tells me you need:

$scope.up = function() {
    if( {ALREADY_UP_VOTED} ) {
       //perform remove upvote
    } else {
       //perform upvote 
    }
}

EDIT: (with dfsq's comment in mind)

I guess you could look at your $scope.votedMsg variable:

$scope.up = function() {
    if( $scope.votedMsg == "VOTED" ) {
       // perform remove upvote

       // remove upvote thing..
       $scope.votedMsg = "";
    } else {
       //perform upvote 
    }
}

1 Comment

i have updated my question, sorry for my poor explanation and didn't state my question clearly

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.