UTSAV BHAGAT UTSAV BHAGAT - 5 months ago 15
Javascript Question

adding question_id to list of bookmarks in user schema angular

Schema:

var UserSchema = new Schema({
ques_bookmarks: [{ type: String }],
})


Controller:

.controller('questionsController', function(questionsFactory, $routeParams, $scope) {
var that = this;
questionid = $routeParams.id;
stats = false;

var getallQuestions = function() {
questionsFactory.getQuestions(function(data) {
that.questions = data;
console.log(data)
})
}
getallQuestions();
this.getthatQuestion = function() {
questionsFactory.getthatQuestion(questionid, function(data) {
questionsFactory.checkBookmark(questionid, function(response) {

if (response == "bookmarked") {
data.stats = true;
} else {
data.stats = false;
}
})
that.question = data;
})
}
this.addbookmark = function(qId) {
questionid = qId;

questionsFactory.addBookmark(qId, function(response) {
that.getthatQuestion();
})
}
this.removebookmark = function(qId) {
questionid = qId;

questionsFactory.removeBookmark(qId, function(response) {
that.getthatQuestion();
})
}

this.checkbookmark = function(question) {
questionsFactory.checkBookmark(question._id, function(response) {
if (response == "bookmarked") {
question.stats = true;
} else {
question.stats = false;
}
})
}
});


Factories:

.factory('questionsFactory', function($http, AuthToken, $route) {
var factory = {};
var token = AuthToken.getToken();
var userid = AuthToken.getid();

factory.getQuestions = function(callback) {
$http({
url: 'api/all_questions',
method: 'GET',
headers: {
'x-access-token': token
}
}).then(function(response) {
callback(response.data)
})
}

factory.getthatQuestion = function(info, callback) {
$http({
url: 'api/one_question',
method: 'GET',
headers: {
'x-access-token': token
},
params: {
question_id: info
}
}).then(function(response) {
console.log('[FACTORY] one question data:', response.data);
callback(response.data)
})
}

factory.addBookmark = function(info, callback) {
$http({
url: 'api/add_bookmark_ques',
method: 'POST',
headers: {
'x-access-token': token
},
params: {
'user_id': userid
},
data: {
'ques_id': info
}
}).success(function(data) {
console.log('add bookmark: ' + data);
callback()
})
}

factory.checkBookmark = function(info, callback) {
$http({
url: 'api/check_bookmark_ques',
method: 'POST',
headers: {
'x-access-token': token
},
params: {
'user_id': userid
},
data: {
'ques_id': info
}
}).success(function(data) {
console.log('check bookmark: ' + data);
callback(data)
})
}

factory.removeBookmark = function(info, callback) {
$http({
url: 'api/remove_bookmark_ques',
method: 'POST',
headers: {
'x-access-token': token
},
params: {
'user_id': userid
},
data: {
'ques_id': info
}
}).success(function(data) {
console.log('remove bookmark: ' + data);
callback()
})
}
return factory
})


HTML:

<div ng-controller="questionsController as questCtrl">
<div ng-repeat="question in questCtrl.questions>
<div ng-init="questCtrl.checkbookmark(question)">
<div ng-if="question.stats" ng-click="questCtrl.removebookmark(question._id)" class="glyphicon glyphicon-heart"></div>
<div ng-if="!question.stats" ng-click="questCtrl.addbookmark(question._id)" class="glyphicon glyphicon-heart-empty"></div>
</div>
</div>
</div>


When I click on the glyphicon to add/remove it to the list of bookmarks, the database successfully updates but the icon doesn't change. it only changes when the page is refreshed.

How to resolve this?

Answer

When you change your bookmarks in database you dont actually changing the value on client side, just on the server side. the below codes doesn't do anything for that :

   this.addbookmark = function(qId){
    questionid = qId;

    questionsFactory.addBookmark(qId, function(response){
        that.getthatQuestion();
    })
}
this.removebookmark = function(qId){
    questionid = qId;

    questionsFactory.removeBookmark(qId, function(response){
        that.getthatQuestion();
    })
}

and the method here actually returns another javascript object instance(named data that overrides the bound that.question) that is not bound to view so changing it will not effect your view:

  // the problem is that
    this.getthatQuestion = function(){
        // when you call two asynchronus functions
        questionsFactory.getthatQuestion(questionid, function(data){
            //first one returns result and you gave value already to the angular
            questionsFactory.checkBookmark(questionid, function(response){
            // second one return later and you havent told angular about this response
            if(response == "bookmarked"){
                data.stats = true;  
            }
            else{
                data.stats = false;  
            }
             // with the each function below we find view-bound object and change its property so angular will know about this change.
             angular.forEach(that.questions,function(e){
                if(e._id == questionid)
                    e.stats = data.stats; 
             });
        })
        })
    }

Ps : I think you need to try better naming conventions / casing as i could understand what your code does at 4th read and also you have misunderstood what factories does and what services does.

Comments