Search code examples
javascriptangularjsfirebaseionic-frameworkfavorite

Make favorite button shows marked without reloading page Ionic


I write an Ionic page that shows a list of posts, each post has a favorite button (star icon) for users to mark it. When I click on a favorite button, data will be inserted into the database, but the icon is not immediately marked. After reloading page, it's marked. So how to make the icon marked right away when clicking on it.

Here is my page code, it uses $scope.post_infos to show data, if variable "marked" exists, favorite button will show star icon, otherwise outline star icon:

<ion-list>  //ng-controller is recuitmentCtrl
<div ng-repeat="post_info in post_infos" >
     <ion-item>
     <div class=" item-button-right">
          <a ng-click="showContent(post_info.id)">
             <div class="post">
                  <div class= "title">{{post_info.title}}</div>
                  <div class= "description">{{post_info.description}}</div>
             </div> 
          </a>
          <button class="button button-icon i" ng-click="isFavorite(post_info.id)">
             <i ng-class="{'icon ion-android-star-outline': !post_info.marked, 
                        'icon ion-android-star': post_info.marked}"></i>
          </button>
     </div>
     </ion-item>
</div>
</ion-list>

In my controller.js

.controller('recuitmentCtrl', ['$scope', '$state', function ($scope, $state,) {

    var ref = firebase.database().ref('posts');
    var titles, descriptions;
    $scope.post_infos = [];

    ref.on('value' ,function(snapshot){
        var userID = firebase.auth().currentUser.uid;
        $scope.post_infos = [];

        snapshot.forEach(function(childSnapshot){

            var marked = firebase.database().ref('users/'+ userID + '/favorites/' + childSnapshot.key);
            marked.on('value', function(snapshot_user){
            var obj = { 
                "id":           childSnapshot.key,
                "title":        childSnapshot.val().title,
                "description":  childSnapshot.val().description,
                "marked":       snapshot_user.child("marked").val()
            };
            $scope.post_infos.push(obj);
        })
    });
});

    $scope.showContent = function(param){
        $state.go('postdetail',{postID: param});
    };

    $scope.isFavorite = function(postID){
       var userID = firebase.auth().currentUser.uid;
       var userRef = firebase.database().ref('users/'+ userID + '/favorites/' + postID);
       userRef.set({
          marked: true
       }).then(function(result){
    });
}

}])

Here is my database:

Firebase database


Solution

  • You need to update the variable post_info when it's marked as favorite, here are two ways to do it:

    Controller

    $scope.isFavorite = function(post){
       var userID = firebase.auth().currentUser.uid;
       var userRef = firebase.database().ref('users/'+ userID + '/favorites/' + post.id);
       //post.marked = true; //instant feedback
       userRef.set({
          marked: true
       }).then(function(result){
           //post.marked = true; //will mark as favorite as soon as the server accepts the request
       });
    

    Template

    <button class="button button-icon i" ng-click="isFavorite(post_info)">
             <i ng-class="{'icon ion-android-star-outline': !post_info.marked, 
                        'icon ion-android-star': post_info.marked}"></i>
    </button>