Here is the schema of the principal object:
var newsSchema = new Schema({
headline: String,
paragraph: String,
imgURI: String,
imgThumbURI: String,
imgCaption: String,
addedOn: Date,
addedBy: {
type: ObjectID,
ref: 'usr'
}
});
var News = mongoose.model('news', newsSchema);
...and the schema for the addedBy:
var usr = new Schema({
username: String,
avatar: {
type: ObjectID,
ref: 'avtr'
},
href: String
});
var UserModel = mongoose.model('usr', usr);
So far so good. All works. Then in Angular client I retrieve a news object, but the addedBy value is not the desired object, but an ObjectId:
{
"headline":"Shocking news from the Neverland!",
...
"addedBy":"520e9aac9ca114914c000003", // <-- the offender!!
"addedOn":"2013-08-16T21:33:32.294Z",
"_id":"520e9aac9ca114914c000001",
"__v":0
}
When I want an object like this:
{
"headline":"Shocking news from the Neverland!",
...
"addedBy":{
"username":"Peter"
"avatar":{
"src":"../images/users/avatars/avatar1.png",
"ststus":"happy"}
}
"addedOn":"2013-08-16T21:33:32.294Z",
"_id":"520e9aac9ca114914c000001",
"__v":0
}
So yes, I want to all (no mater how deeply) nested ObjectId's be replaced with their respective objects from the DB, before the principal object is sent to the angular client. The API I am building is deep and complex and it would be nice if the angular client could to receive from my Express server an object which is ready to be thrown into a scope.
How do I change the following '/news' route:
app.get('/news', function(req, res, next){
News.
find().
exec(function(err, nws){
if(err) {res.writeHead(500, err.message)}
res.send(nws);
});
});
to accomplish just that, so I can fully access the complete (nested) object from angular like this:
angular.module('App', ['ngResource'])
.controller('NewsCtrl', function($scope, $resource){
var News = $resource('/news');
var news = News.query();
$scope.news = news;
});
and then on the website access the api like this:
<img class="avatar-img" src="{{ news[0].addedBy.avatar.src }}">
I very much appreciate your time, cheers Jared
1 Create ObjectId. To create a new objectID manually within the MongoDB you can declare objectId as a method. ... 2 Define Specific ObjectId Hexadecimal. If you want to define your own unique hexadecimal value then MongoDB will enable you to perform this action. 3 Get ObjectId Hexadecimal String. ...
ObjectId : ObjectId class is a 12 byte binary BSON type, in which 4 bytes of timestamp of creation, 5 bytes of random value and 3 bytes of incrementing counter. ObjectId is the default primary key for MongoDB document and usually found in “_id” field. eg : { "_id" : ObjectId ("54759eb3c090d83494e2d804") }
ObjectId: ObjectId class is a 12-byte binary BSON type, in which 4 bytes of the timestamp of creation, 5 bytes of a random value, and 3 bytes of incrementing counter. ObjectId is the default primary key for MongoDB documents and is usually found in “_id” field. PyMongo: PyMongo is a native Python driver for MongoDB.
MongoDB is flexible for storing semi-structured and unstructured data. MongoDB is used for high-volume data storage and can scale horizontally. ObjectId: ObjectId class is a 12-byte binary BSON type, in which 4 bytes of the timestamp of creation, 5 bytes of a random value, and 3 bytes of incrementing counter.
As @WiredPrairie said, you need to use the populate function Populate Mongoose Documentation
Your query should look like this:
app.get('/news', function(req, res, next){
News.
find().
populate("addedBy").
exec(function(err, nws){
if(err) {res.writeHead(500, err.message)}
res.send(nws);
});
});
There are plenty of different things that you can do with populate, for example to bring only the username field of the "addedBy" document, you can do
populate("addedBy","username")
or if you don't want bring one specific field, doing something like this:
populate("addedBy","-username")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With