I have a $http request which returns an object of a user.
$scope.profile = $http.get('api/users/' + $stateParams.userId).success(function(data) {
console.log(data);
});
How do i actually assign for example a user.username to $scope.profileUsername?
Copied from the console...
Object
__v: 0
_id: "56a1832a36dc3d0e00c7aa3f"
aboutme: "<p>Im the Boss.</p>"
additionalProvidersData: Object
county: "waterford"
created: "2016-01-22T01:17:30.863Z"
displayName: "Chris"
firstName: "Chris"
gender: "male"
imageURL: "/modules/users/client/img/profile/saveme-placeholder.png"
profileImageURL: "../modules/users/client/img/profile/avatars/2/45.png"
provider: "local"
roles: Array[2]
updated: "2016-02-09T02:55:38.744Z"
username: "abcdef"
__proto__: Object
Try this.
$http.get('api/users/' + $stateParams.userId).success(function(data) {
$scope.profileUsername = data.username;
});
The return values of the $http methods are promises, not the data.
This is due to their asynchronous nature and the function you pass as a callback is only executed once the HTTP requests returns, so do anything you want to do with the data, you gotta do it in the callback function.
EDIT:
You could also do it like this
$http.get('api/users/' + $stateParams.userId).success(function(data) {
$scope.profile = data;
});
That way you can have all the data in one variable, assuming you need all of it.
In your templates you can then just access the properties with the dot notation (profile.username).
Should be
$http.get('api/users/' + $stateParams.userId).success(function(data) {
$scope.profile=data;
});
It should be accessible on views like {{profile.username}}
Related
I am using firebase, and angularfire.
there are so many ways to do CRUD with the Firebase Api
actually, I still don't get what is specific difference for using
$add with $firebaseArray
.push() method
.set() method
I think they are technically same, I prefer to use .set method() without knowing the exact reason, why I'd using that. is there any specific reason to not use it? what is exactly $firebaseArray did? if we could just declare basic reference variable.
in this case:
var usersRef = Ref.child('users');
$scope.createUser = function() {
$scope.userRef.child($id).set({
name: name
});
};
or
$scope.data = $firebaseArray(Ref.child('users'));
$scope.createUser = function() {
$scope.data.child($id).$add({
name: name
});
};
thank you.
If I have the following data tree in Firebase:
{
users:
{
key: { name:"bob" }
}
}
When I do an $add, I will create a new item in the tree
$scope.data.child('users').$add({
name: name
});
Since $add uses the Push method in Firebase, new random Key will be used when pushing data to the child.
{
users:
{[
key: { name:"bob" },
key2: { name:"name" }
]}
}
If I do a set on the same Users object, I will overwrite the data that is already there. So, in your example, without specifying a key, you will overwrite the entire user object.
$scope.userRef.child('users').set({
name: name
});
};
This will result with this data
{
users:
{
name: "name"
}
}
This happens because any null values you pass to the Set method will delete any data that was originally there.
Passing null to set() will remove the data at the specified location.
https://www.firebase.com/docs/web/api/firebase/set.html
I am trying to access my Products collection in Minimongo in the html page. When I am in my browser console, I am able to type Products.findOne(); and it will return a product.
However, when I try to return a product from my template helper, I get undefined. Thoughts anyone?
Template.Tires.onRendered(function() {
console.log(Products.findOne());
//after I return a product item, I need to modify its properties manually after it has loaded into the client
});
Simple answer:
Do whatever modification you need to do on the collection within the helper function and then return a JS object. For instance if you collection looks something like this:
SomeColleciton
_id
type: String
birthday:
type: Date
firstname:
type: String
lastname:
type: String
timezone:
type: Integer
you can do the following to transform it
Template.Tires.helpers({
user: function(userId) {
var u = SomeCollection.findOne(userId);
var age = calcAge(u.birthday);
var ifworkinghour = calcifworkinghour(u.timezone);
return {name: u.firstname + ' ' + u.lastname, age: age, workinghour: ifworkinghour}
});
When I try to save my document, I'm getting a VersionError: No matching document found error, similar to this SO question.
After reading this blog post, it seems that the problem is with the versioning of my document. That I'm messing with an array and so I need to update the version.
However, calling document.save() doesn't work for me. When I log out the document before and after the call to save(), document._v is the same thing.
I also tried doing document._v = document._v++ which also didn't work.
Code
exports.update = function(req, res) {
if (req.body._id) { delete req.body._id; }
User.findById(req.params.id, function(err, user) {
if (err) return handleError(res, err);
if (!user) return res.send(404);
var updated = _.extend(user, req.body); // doesn't increment the version number. causes problems with saving. see http://aaronheckmann.blogspot.com/2012/06/mongoose-v3-part-1-versioning.html
console.log('pre increment: ', updated);
updated.increment();
// updated._v = updated._v++;
console.log('post increment: ', updated);
updated.save(function(err) {
if (err) return handleError(res, err);
return res.json(200, user);
});
});
};
Output
pre increment: { _id: 5550baae1b571aafa52f070c,
provider: 'local',
name: 'Adam',
email: 'azerner3#gmail.com',
hashedPassword: '/vahOqXwCwKQKtcV3KBQeFge/YB0xtqOj+YDyck7gzyALA/IP7u7BfqQhlVHBQT26//XfBTkaOCK2bQXg65OzA==',
salt: 'MvzXW7D4xuyGQBJNeFRoUg==',
__v: 32,
drafts: [],
starredSkims: [],
skimsCreated: [ 5550cfdab8dcacd1a7892aa4 ],
role: 'user' }
post increment: { _id: 5550baae1b571aafa52f070c,
provider: 'local',
name: 'Adam',
email: 'azerner3#gmail.com',
hashedPassword: '/vahOqXwCwKQKtcV3KBQeFge/YB0xtqOj+YDyck7gzyALA/IP7u7BfqQhlVHBQT26//XfBTkaOCK2bQXg65OzA==',
salt: 'MvzXW7D4xuyGQBJNeFRoUg==',
__v: 32,
drafts: [],
starredSkims: [],
skimsCreated: [ 5550cfdab8dcacd1a7892aa4 ],
role: 'user' }
The issue here has to do with using __v and trying to update it manually. .increment does not actually perform an increment immediately, but it does set an internal flag for the model to handle incrementing. I can't find any documentation on .increment, so I assume it is probably for use internally. The problem stems from trying to combine .extend with an object that already has __v (there are two underscores by the way, not that document.__v++ affects the model internally anyway) in addition to using .increment.
When you use _.extend it copies the __v property directly onto the object which seems to cause problems because Mongoose cannot find the old version internally. I didn't dig deep enough to find why this is specifically, but you can get around it by also adding delete req.body.__v.
Rather than finding and saving as two steps, you can also use .findByIdAndUpdate. Note that this does not use __v or increment it internally. As the other answer and linked bug indicate, if you want to increment the version during an update you have to do so manually.
Versioning was implemented to mitigate the doc.save() by design (not Model.update etc). But if you want you can try the following instead:
{$set: {dummy: [2]}, $inc: { __v: 1 }}
However this was a confirmed-bug according to the link
Please validate your mongoose version from the milestone of the above issue.
Thanks :)
For my app, I've created a service for Address, which allows me to manipulate Address objects for any given user. Aside from my standard CRUD functions, I need to have one function to list any address for a specified Parse.User.
services.js
.factory('Address',['$http', 'PARSE_CREDENTIALS', function ($http,PARSE_CREDENTIALS) {
return {
// constrain to User ID
getAll: function(userId) {
return $http.get('https://api.parse.com/1/classes/Address', {
headers: {
'X-Parse-Application-Id': PARSE_CREDENTIALS.APP_ID,
'X-Parse-REST-API-Key': PARSE_CREDENTIALS.REST_API_KEY,
'Content-Type' : 'application/json'
},
params: { "userId": userId }
});
},
// ...get(), edit(), add(), delete()
controllers.js
.controller('AddrCtrl', ['$scope', '$state', '$stateParams', '$rootScope', 'Address',
function($scope, $state, $stateParams, $rootScope, Address) {
Address.getAll($rootScope.user.id)
.success( function(data) {
console.log(data);
$scope.addresses = data.results;
})
}]);
In my Angular template, the view does return Address objects. But it returns all the Address objects when it should only be returning the Address objects with a corresponding userId. To clarify, the Address class has a userId pointer column. Each address only has one User.
Here is the log message that AddrCtrl returns in the console:
Object {results: Array[2]}
results: Array[2]
0: Object
firstName: "(test)"
lastName: "test"
// more unrelated properties
objectId: "yUEuFjLlzs"
updatedAt: "2014-12-02T20:17:55.608Z"
userId: Object
__type: "Pointer"
className: "_User"
objectId: "q1KADkp4i1"
I'm assuming that the issue lies somewhere in my $http.get() function. Ultimately, my questions is this: why does my params option not constrain my data.results to just the Address objects associated with one Parse.User?
Answer I am not looking for:
Return all Address objects and only save the ones matching Parse.User.current().id into $scope.
You need to use where clause to perform the query.
If the data type of userId is Pointer, you should write as following:
{"where": JSON.stringify({
"userId": {"__type":"Pointer","className":"_User","objectId":"userId"}}
)}
I'm returning my model to my view something like this:
User.findOneById('xxx', function(err, result){
res.render('viewName', {user: result});
}
Then, on my view, I have a script block, that I'm trying to assign the user to a variable:
<script id="foundBusiness" type="text/javascript">
var user = <%-user%>
</script>
This renders as follows as the HTML
var user = { __v: 0,
_id: 5315b7b9caaf52e624070002,
firstName: 'Alex',
lastName: 'Brown',
password: '$2a$10$Zs/6JmB3Rq5dddHvjZNUse9vl.8z3hJO.LUGBqMEE.vBMk4lVuav.'}
My issue is around the _id field
This is obviously not valid Javascript, and as such, an error occurs:
SyntaxError: Unexpected token ILLEGAL
What am I doing wrong?
From the horse's mouth
ObjectIds contain the raw MongoDB binary and don't work with templating so we provide the id convenience method to convert them to hexstrings
https://github.com/LearnBoost/mongoose/issues/548
One possible solution -
User.findOneById('xxx', function(err, result){
result._id = result._id.toHexString();
res.render('viewName', {user: result});
}
I think assigning it to result.id would also work.
result._id = result.id;