Reputation: 37
I'm trying to do a single routing back and forth to mongodb, but it seems that on the client side I can't retrieve the data out of the promise received from $resource. On the HTML page there's a button who has ng-click to this following function:
$scope.getToken = function() {
console.log('$scope.getToken()');
authenticationService.getToken($scope.data.email).then(function(result) {
$scope.data.token = result;
});
}
The result received is:
object "m", with fields - 0: "j", 1: "6", 2: "o", 3: "p", 4: "E", 5: "7", 6: "X", 7: "t", $promise: d, $resolved: true, proto: Object
As you can see I receive the token generated, the database seems to work fine and the function invoking as well.
The service on the client side that receive the answer has a function:
function getToken(userEmail) {
var deferred = $q.defer();
$resource(baseUrl + '/getToken').save({
email : userEmail
}, function(result, error) {
if(result) {
deferred.resolve(result);
}
else {
deferred.reject(error);
}
});
return deferred.promise;
}
The function on the server side that sent this:
var router = require('express').Router();
var authenticator = require('../utils/authUtils');
router.post('/getToken', function(request, response) {
authenticator.getToken(
function(error, result) {
if(error) {
//handle error
}
else if(result) {
response.json(result);
}
}
);
And in authUtils.js:
var mongoUtils = require('./mongoUtils');
getToken : function(callback) {
var genToken = randToken.generate(8);
mongoUtils.query(COLLECTIONS.TOKENS, {'token': { $eq: genToken } },
function(error, result) {
if((result && result.length) || error) {
//handle error or duplicates
}
else if(result) {
callback(null, genToken);
}
}
);
}
And in mongoUtils:
query : function(collectionName, query, callback) {
_db.collection(collectionName).find(query).toArray(function (error, result) {
console.log('Utils.query');
if(error) {
//handle error
}
else {
callback(error, result);
}
});
}
Why the server side sends the answer inside an object along with the promise, and how should I handle it?
Upvotes: 1
Views: 595
Reputation: 878
So you have 3 parts in your questions, why an object, why promise and how to handle it.
1: Why Inside an object ?
According to Angular official $resource page $resource When you are using $resource
The returned resource is always object, also in your API (Server side) you are sending the response back as a json object
so you will obviously get object.
else if(result)
{
response.json(result);
}
2: Why Promise ?
$resource
and $http
both return a promise, REST is a subset of HTTP. This means everything that can be done via REST can be done via HTTP but not everything that can be done via HTTP can be done via REST. That is why $resource uses $http internally. $resource is built on top of $http. so $promise
is for sure. for reference Why Promise
3: How to Handle it
I'm not exactly sure what do you mean by "How to Handle It" since you already have the object I would assume you meant to separate the actual generated token data object and leave everything else, if that's the case than you can simply assign the data within the result object the your $scope
.
what you are doing is assigning the entire object to $scope
which has all other objects
$scope.data.token = result;
what you can do is simply assign the generated token to $scope.data.token
for instance:
$scope.data.token = result.genToken;
Hope this will answer the question.
Upvotes: 0
Reputation: 24109
The reason its being returned as an indexed object is because of
toArray
in:
_db.collection(collectionName).find(query).toArray(function...
A possible solution would be to not use toArray
on a string or to call slice
before sending back the result:
response.status(200).json({token: Array.prototype.slice.call(result)})
Another possibility as I may not understand your question completely is try:
authenticationService.getToken($scope.data.email).$promise.then(...)
If it is a ngResource I have accessed the then
via $promise
, just a thought.
Upvotes: 1