AngularJS Voting System - Multi-Voice Prevention

I am trying to create a voting system using AngularJS with Ionic Framework. I am using ng-repeat to loop through a series of user posts from a JSON array. Each message has an upvote and downvote button. After one of them is selected, I have the button disabled on this post. The problem I'm currently running into is that this button is disabled regardless of whether the app is reopened. My goal is to prevent polyvoting. I am currently using this method to disable a button after clicking it:

<button class="button button-small button-light" ng-click="upThread({{thread.id}})" ng-disabled="upDisabled[thread.id]">  
  <i class="icon ion-thumbsup"></i>
</button>
<button class="button button-small button-light" ng-click="downThread({{thread.id}})" ng-disabled="downDisabled[thread.id]">
  <i class="icon ion-thumbsdown"></i>
</button>


$scope.upDisabled = {};
$scope.downDisabled = {};

$scope.upThread = function(id) {
    ...
    $scope.upDisabled[id] = true;
    $scope.downDisabled[id] = false;
}

$scope.downThread = function(id) {
    ...
    $scope.downDisabled[id] = true;
    $scope.upDisabled[id] = false;
}`

      

And it works great for disabling buttons. Now the problem is that I require the Cache for the controller to be false, otherwise my new posts are not updated in the view when added. This means that when you restart the app or switch between routes / views, the buttons re-enable, which is not what I want. Also, setting the cache to true does not disable the buttons after reopening the application. I tried using localstorage to store $ scope.upDisabled and $ scope.downDisabled, but it ruins the JSON formatting. I tried remote storage and got the same result. For example, $ scope.upDisabled and $ scope.downDisabled store data like this:

{"2": true, "3": false, "4": true}

etc. But since storing in localstorage or database requires me to use JSON.stringify, you can guess that these quotes are causing problems and I ended up nesting in JSON too. Thus, data from localstorage does not return the correct format. My known problems / options are twofold.

  • Is there a better solution to disable these buttons permanently?
  • How to properly format the JSON coming out of LocalStorage?

Something else to note: since this is a mobile / hybrid application using Ionic, I don't use cookies, but I created a token system to act in a similar way.

Edit: Thanks to those who responded and your suggestions. I am currently using a MySQL database to track votes (later I can switch to SQLite) @aorfevre: I have already looked at the SQLite plugin and will probably use it in the future. I finally got everything I needed.

$scope.upDisabled = {};
$scope.downDisabled = {};
$scope.upCheck = {};
$scope.downCheck = {};

...Votes Loading function up here
...Thread loading Function up here
.finally(function(){
angular.forEach($scope.threads,function(value,index){
    angular.forEach($scope.upCheck,function(value2,index){
        if(value.id == value2.threadID)
        {
            $scope.upDisabled[value.id] = true;
            $scope.downDisabled[value.id] = false;
        }
    })
})

angular.forEach($scope.threads,function(value,index){
    angular.forEach($scope.downCheck,function(value2,index){
        if(value.id == value2.threadID)
        {
            $scope.downDisabled[value.id] = true;
            $scope.upDisabled[value.id] = false;
        }
    })
})
}
$scope.loadVotes();
$scope.loadThreads();

      

As for the server side (PHP with Laravel Framework):

public function upvoteThread($id, $token)
{
    $thread = Thread::find($id);
    $score = $thread->score;
    $score = $score + 1;
    $thread->score = $score;
    $thread->save();

    $voted = ThreadVote::where('threadID','=',$id)->where('token','=',$token)->get();

    if($voted->isEmpty())
    {
        $upVote = new ThreadVote;
        $upVote->threadID = $id;
        $upVote->token = $token;
        $upVote->upVote = 'true';
        $upVote->downVote = 'false';
        $upVote->save();
    } 
    else 
    {
        DB::table('thread_votes')
            ->where('threadID', '=', $id)
            ->where('token','=',$token)
            ->update(array('upVote' => 'true', 'downVote' => 'false')
        );
    }

    return Response::json(array('status'=>1))->setCallback(Input::get('callback'));
}

public function getUpVotes($token)
{
    $votes = ThreadVote::where('token','=',$token)
    ->where('upVote','=','true')
    ->select('threadID','upVote')
    ->get();

    return Response::json($votes)->setCallback(Input::get('callback'));
}

...Similar downVote Function...

      

The way it is. When the button is clicked, it saves the user's token, threadID, and votes to the database. When the view is loaded, this token and threadID based information is loaded as a JSON array associated with the Thread array, and if threadID and thread.id are the same then it is inserted into the up / downdisabled area as "threadID": bool ("1" : true, for example).

+3


source to share


1 answer


I recommend you implement a DB if you are managing a huge message volume.

I am using localStorage for multiple non-db storage settings.



So if you only target ios / android I recommend you https://github.com/litehelpers/Cordova-sqlite-storage

If you are targeting Windows Phone 8.1 the implementation is not trivial and I am running into some issues related to the librairy framework of WindowsPhone and C ++ compilation (more details here: https://issues.apache.org/jira/browse/CB- 8866 )

0


source







All Articles