Reputation: 23
I'm using the following code, which is also working
'use strict';
const Profile = require('../database/shemas/profileSchema');
const ProfileHelper = require('../helpers/profileHelper');
const logger = require('../utils/logger');
const createUpdateProfile = (req, res) => {
//Fillout Schema
let uuid = req.user.identities[0].id;
let provider = req.user.identities[0].provider;
let email = req.user.email;
let firstName = req.user.name.split(' ').slice(0, -1).join(' ');
let lastName = req.user.name.split(' ').slice(-1).join(' ');
let pictureUrl = req.user.picture;
let profileToSafe = new Profile({
uuid,
provider,
email,
firstName,
lastName,
pictureUrl
});
//createUpdate
if (!!!uuid) {
res.status(400).send('Invalid argument supplied');
} else {
Profile.findOne({ uuid }).then(object => {
if (object !== null) {
var upsertData = profileToSafe.toObject();
delete upsertData._id;
delete upsertData.uuid;
delete upsertData.provider;
Profile.update({ uuid }, upsertData, { upsert: true }, function (err, raw) {
if (err) {
console.log('callback -> err', err);
}
console.log('callback -> raw', raw);
res.status(200).send('Successful operation');
});
} else {
profileToSafe.save();
res.status(200).send('Successful operation');
}
})
}
}
This is my schema
'use strict';
// Mongoose schema definitions
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Profile Schema
const profileSchema = new Schema({
uuid: {
type: String,
required: true,
unique: true
},
provider: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true,
trim: true
},
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
birthday: {
type: String,
default: ""
},
pictureUrl: {
type: String,
default: ""
}, // Later we can add a default image for users who use cloud directory login
onboardingDone: {
type: Boolean,
required: true,
default: false
}
}, {
timestamps: true, // Add CreatedAt and updatedAt fields automatically
strict: 'throw'
});
const Profile = mongoose.model('Profile', profileSchema);
module.exports = Profile
But the trick was, that I needed to delete the id
delete upsertData._id;
A colleague persists that this is due wrong usage of
let profileToSafe = new Profile({ ...
I tried different variations but none of them worked. Is there really another (more) correct way of doing what I want?
Edit: I did what @Sridhar suggested but now I'm running into a problem with the timestamp. Even when I delete it from the schema.
Upvotes: 0
Views: 186
Reputation: 11786
You can use mongoose's findOneAndUpdate() with upsert:true
option.
Finds a matching document, updates it according to the update arg, passing any options, and returns the found document (if any) to the callback.
Options
upsert: bool - creates the object if it doesn't exist. defaults to false.
Making those changes to your code
'use strict';
const Profile = require('../database/shemas/profileSchema');
const ProfileHelper = require('../helpers/profileHelper');
const logger = require('../utils/logger');
const createUpdateProfile = (req, res) => {
const uuid = req.user.identities[0].id;
const provider = req.user.identities[0].provider;
const email = req.user.email;
const firstName = req.user.name.split(' ').slice(0, -1).join(' ');
const lastName = req.user.name.split(' ').slice(-1).join(' ');
const pictureUrl = req.user.picture;
if (!uuid) {
return res.status(400).send('Invalid argument supplied');
}
Profile.findOneAndUpdate({
uuid
}, {
provider,
email,
firstName,
lastName,
pictureUrl,
$setOnInsert: {
createdAt: Date.now()
},
updatedAt: Date.now()
}, {
upsert: true
}).then(() => {
res.status(200).send('Successful operation');
}).catch((err) => {
console.log('callback -> err', err);
// You can send appropriate response here
});
}
Upvotes: 1