问题
I have the following model, let's say it describes a book:
module.exports = {
attributes: {
name: {
type: 'String',
required: true
},
type: {
type: 'string',
required: true
},
book_id: {
type: 'integer'
}
}
}
Here the 'type' attribute is the genre of the book, for example HorrorBook. I have a separate model for HorrorBooks, FantasyBooks and such, since the structure of the models differs from each other so much, they have fields the other doesn't have etc, which is why I can't just use a single generic Book-model. HorrorBook, FantasyBook etc each have their own 'id' fields, meaning there can be both a HorrorBook and a FantasyBook with the same id. When creating the book, I have a beforeCreate function that also creates an entry in HorrorBook or FantasyBook depending on the 'type' attribute of the book.
What I'm trying to do is that on queries on Book from the frontend, I'd like to include the relevant information of the book in an 'information' attribute, which is for example a HorrorBook entry.
toJSON: function() {
var obj = this.toObject();
switch (obj.type) {
case 'HorrorBook':
HorrorBook.find({id: obj.book_id})
.exec(function(err, book_info) {
obj.book_info = book_info;
return obj;
})
}
}
However, this leads to the toJSON just returning null all the way. What I'm assuming is that the query being asynchronous makes it too slow or something, so it doesn't make it to the 'return' call at all. So what should I do about this? Is there a way to succeed in what I'm trying, or should I change my approach somehow?
回答1:
What I'm assuming is that the query being asynchronous makes it too slow or something, so it doesn't make it to the 'return' call at all.
What's happening is that toJSON()
is sync'ed and it's returning whatever comes out of HorrorBook.find({id: obj.book_id}).exec()
, undefined
sounds about right.
If you need to run something async your best bet is to create an async toJSON()
instance method, for example (not tested):
toJSONAsync: function(callback) {
var obj = this.toObject();
switch (obj.type) {
case 'HorrorBook':
HorrorBook.find({id: obj.book_id})
.exec(function(err, book_info) {
obj.book_info = book_info;
callback (obj);
})
}
}
And now you can get your result by doing:
book.toJSONAsync(function(json){
console.log(json);
})
来源:https://stackoverflow.com/questions/30164255/sails-js-waterline-executing-waterline-queries-in-tojson-function-of-a-model