我有一个具有以下属性的Mongo集合:
{
"_id" : ObjectId("384f1f06f72cc1b566e32f98"),
"num" : 41,
"product" : ObjectId("5c8921d8f9f7be241c0b02cf"),
"data" : {
"phone" : "123123123",
"email" : "email@email.com",
"name" : "John",
"_id" : ObjectId("5ca34689ac024b579991fe26")
},
"generatedCode": "01-1FCS3";
}
根据产品的类型(您可以看到它是一个对象),我希望每次创建新元素时都生成不同的代码
ProductSchema.pre('save', function(next) {
if ((typeof this.generatedCode === 'undefined') || !this.generatedCode) {
ProductSchema.find({_id: this.product}, function(error, existingProduct) {
if (error) {
next(Error(error));
}
else {
if (existingProduct.length > 0) {
console.log("Type of product: "+ existingProduct[0].type);
generateCode(this,existingProduct[0].type).then(function(doc) {
console.log('Code generated:' + doc.generatedCode);
next();
}, function(err) {
console.error(err);
next(err);
});
}
else {
next(new Error("Error: Not found."));
}
}
});
} else {
next();
}
});
function generatedCode(doc,productType){
var deferred = q.defer();
try {
console.log("Product type = "+ invoiceType);
var ObjectId = require('mongoose').Types.ObjectId;
var generatedCode = '';
switch(productType) {
case 'TYPE1':
generatedCode = 'COD01-'+ random(5);
break;
case 'TYPE2':
generatedCode = 'COD02-'+ random(5);
break;
default: // other types
generatedCode = 'COD03-'+ random(5);
}
console.log("generatedCode = "+ generatedCode);
var InvoiceModel = mongoose.model('Invoice', InvoiceSchema);
// check that there are no records with that code
InvoiceModel.find({generatedCode: generatedCode}, function(err, existingInvoice) {
console.log('Find: '+ generatedCode);
if(err) {
console.log(err);
deferred.reject(err);
}
if(existingInvoice.length > 0) {
console.log('Alredy exists ' + generatedCode + ' in db');
generatedCode(doc,productType).then(function(doc) {
deferred.resolve(doc);
}, function(err) {
deferred.reject(err);
});
}
else {
console.log("generatedCode = "+ generatedCode);
console.log("Doc = "+ doc);
doc.generatedCode = generatedCode;
deferred.resolve(doc);
}
});
}
catch(exception) {
console.error(exception);
deferred.reject(new Error(exception.message));
}
return deferred.promise;
}
我不知道为什么会出现错误,但是在“ doc.genicCode = generateCode;”行中返回null似乎doc不存在,而且我不明白发生了什么...
我向您展示了调试:
Type of product: GENERIC
Product type = GENERIC
generatedCode = COD03-8KORD
Find: COD03-8KORD
generatedCode = COD03-8KORD
Doc = null
[ERROR] (node.js:496) -> uncaughtException: Cannot set property 'code' of null
答案 0 :(得分:1)
当您在this
函数内部时,callback
的值将更改。您的代码在这里也发生了同样的情况。当您执行ProductSchema.find
并尝试访问其中的this
时,值将更改。您需要在外部保存对实际值的引用。
ProductSchema.pre('save', function(next) {
if ((typeof this.generatedCode === 'undefined') || !this.generatedCode) {
var that = this; // here create a reference to "this"
ProductSchema.find({_id: this.product}, function(error, existingProduct) {
..
..
// generateCode(this,existingProduct[0].type).then(function(doc) { // YOUR OLD CODE
generateCode(that,existingProduct[0].type).then(function(doc) { // here, change "this" to "that" which is the actual reference of your object
..
..