I'm using an upsert function to serialize users with my backend. I'm using Mongoose's "findOneAndUpdate" with "upsert: true" and "setDefaultsOnInsert: true" set, so that all default values defined in my Schema ought to be used for all parameters that I don't pass to the upsert.
This is my upsert:
let serialize = (params, cb) => {
User.findOneAndUpdate({"fbId" : params.fbId}, params, { upsert: true, setDefaultsOnInsert: true, new: true }, (err, doc) => {
if (err) {
//winston.log
return cb (ErrorTypes.serverError(), null);
}
else if (doc) {
return cb(null, doc);
}
else {
return cb(ErrorTypes.serverError(), null);
}
});
}
For this schema:
const userSchema = new Mongoose.Schema({
fbId: {
type: String,
index: true,
required: "Users must have a facebook ID.",
maxlength: 40
},
firstName: {
type: String,
required: "Users must have a name.",
maxlength: 40
},
lastName: {
type: String,
required: "Users must have a name.",
maxlength: 40
},
gender: {
type: String,
required: "Users must have a gender",
default: "Unknown"
},
ageRange: {
type: String,
default: "Unknown",
maxlength: 25
},
pictureUrl: {
type: String,
required: "Users must have a profile picture."
},
dateJoined: {
type: Number,
required: "Users must have a joined date.",
default: date.getTime()
},
pushId: String,
bookmarks: [{
item: {
type: Mongoose.Schema.Types.ObjectId,
ref: 'Item',
required: "An item id is required to create a bookmark."
},
lastOfferMade: Number,
timeOfferMade: Number,
}], default: [],
offersInCategory: {
type: Object,
validate: object => {
let allowedKeys = ['Furniture', 'Household', 'Electronics', 'Other'];
let correctKeys = Object.keys(object).every(key => allowedKeys.includes(key));
let min = 0;
let correctValues = Object.values(object).every(value => value >= min);
return correctKeys && correctValues;
}
}, default: {
'Furniture': 0,
'Household': 0,
'Electronics': 0,
'Other': 0
},
rejectionsInCategory: {
type: Object,
validate: object => {
let allowedKeys = ['Furniture', 'Household', 'Electronics', 'Other'];
let correctKeys = Object.keys(object).every(key => allowedKeys.includes(key));
let min = 0;
let correctValues = Object.values(object).every(value => value >= min );
return correctKeys && correctValues;
}
}, default: {
'Furniture': 0,
'Household': 0,
'Electronics': 0,
'Other': 0
},
blockedUsers: [{
userId: String,
blockedOn: Number
}], default: [],
blockedBy: [{
userId: String,
blockedOn: Number
}], default: [],
hasSeenWalkThrough: { type: Boolean, default: false },
hasBookmarkedItem: { type: Boolean, default: false },
hasSeenSearchPrompt: { type: Boolean, default: false }
});
Passing in these parameters:
var upsertNewParams = {
fbId: "newUpsertFbId",
firstName: "New upsert - User",
lastName: "Test Last Name - User",
gender: "Male",
ageRange: "18-22",
pictureUrl: "url",
pushId: "12345"
}
My upsert function returns this document:
{ _id: 5931b0efbeadf32d858a7578,
fbId: 'newUpsertFbId',
__v: 0,
firstName: 'New upsert - User',
lastName: 'Test Last Name - User',
pictureUrl: 'url',
pushId: '12345',
hasSeenSearchPrompt: false,
hasBookmarkedItem: false,
hasSeenWalkThrough: false,
blockedBy: [],
blockedUsers: [],
default: [],
bookmarks: [],
dateJoined: 1496429065565,
ageRange: '18-22',
gender: 'Male' }
I can clearly see all other defaults such as "hasSeenWalkthrough" and "blockedBy/blockedUsers/bookmarks" get set, but my "offersInCategory" and "rejectionsInCategory" for whatever reason don't, though I provide default values for those properties like any others. How do I set these default values using an upsert?
via David Tamrazov
No comments:
Post a Comment