How to update a model with Sails JS - sails.js

Ok, I've got the following in one of my controllers:
User.find({email: 'email#example.com'}).then(function (user) {
user[0].field = 'new_value';
user[0].field_2 = 'new_value';
console.log(user[0], 'before saving');
user[0].save();
console.log(user[0], 'after saving');
});
If I console user[0] at this stage I can see the updated fields. However the changes were not saved to the db. If I do the following:
User.find({email: 'email#example.com'}).then(function (user) {
user[0].field = 'new_value';
user[0].field_2 = 'new_value';
user[0].save();
User.find(user[0].id).then(function (updateduser) {
console.log(updateduser[0])
});
});
The updateduser does not have the updated fields... Why is that? How can should I proceed in this case?

Actually
user[0].save();
will return a promise like you have done for User.find().then();
user[0].save() is an asynchronous call so the next call to find the user will run even though the user[0] is not updated in the database.
so place the second find command inside the then of save() function and you will get the updated user.
user[0].save().then(function(err){
User.find(user[0].id).then(function (updateduser) {
console.log(updateduser[0])
});
}))

Why you not use updated() method?
User.find({ email: 'email#example.com' })
.then(function(user) {
if (!user) return res.notFound();
User.update({ eamil: 'eamil#example.com' }, {
field: 'new_value',
field_2: 'new_value'
})
.then(function(updated_user) {
console.log(updated_user);
return res.ok();
})
.catch(function(err) {
sails.log.error(err);
return res.serverError();
});
})
.catch(function(err) {
sails.log.error(err);
return res.serverError();
});

First of all, you want to update only one user data because you are using user[0](I think).
So it is easy to use findOne().
Simple code
User
.findOne({email: 'email#example.com'})
.exec(function(err,user){
if(err || !user) {
//handle here
}
else {
user.key1 = 'new_value';
user.key2 = 'new_value';
user.save(function(err){
if(err){
//handle error
}
console.log('updatedUser',user)
})
}
})
Thank you.

Related

Store collection value to variable

I am having issues storing a value in mongodb to a variable to use within my webpage.
When the user fills out a form on my website, I am trying to figure out what the arrivalTrailer was when the user filled out the arrival form.
So far I have
function previousLoad(loadNumber, callback){
CheckCall.find({loadNumber: loadNumber}).sort({date: 'desc'}).limit(1), function(err, arrival){
if (err){
callback(err, null);
}
else {
callback(null, arrival[0]);
}
}};
previousLoad(loadNumber, function(err, arrival){
if (err){
console.log(err);
}
else{
arrivalTrailer = arrival;
console.log(arrival);
}
});
console.log(previousLoad.arrival);
console.log(arrivalTrailer);
Both output as undefined when I try to console.log the variables.
Thank you :D
Try this :
async function previousLoad(loadNumber) {
try {
let resp = await CheckCall.find({ loadNumber: loadNumber }).sort({ date: -1 }).limit(1)
return resp[0]
} catch (error) {
console.log('error ::', error)
throw new Error (error)
}
}
/** You can return response from previousLoad but to test it, Call it from here */
previousLoad(loadNumber).then(resp => { console.log('successfully found ::', resp)}).catch(err => { console.log('Error in DB Op ::', err)});

Using design documents in pouchDB with crypto-pouch

After testing pouchDB for my Ionic project, I tried to encrypt my data with crypto-pouch. But I have a problem with using design documents. I used the following code:
One of my design documents:
var allTypeOne = {
_id: '_design/all_TypeOne',
views: {
'alle_TypeOne': {
map: function (doc) {
if (doc.type === 'type_one') {
emit(doc._id);
}
}.toString()
}
}
};
For init my database:
function initDB() {
_db = new PouchDB('myDatabase', {adapter: 'websql'});
if (!_db.adapter) {
_db = new PouchDB('myDatabase');
}
return _db.crypto(password)
.then(function(){
return _db;
});
// add a design document
_db.put(allTypeOne).then(function (info) {
}).catch(function (err) {
}
}
To get all documents of type_one:
function getAllData {
if (!_data) {
return $q.when(_db.query('all_TypeOne', { include_docs: true}))
.then(function(docs) {
_data = docs.rows.map(function(row) {
return row.doc;
});
_db.changes({ live: true, since: 'now', include_docs: true})
.on('change', onDatabaseChange);
return _data;
});
} else {
return $q.when(_data);
}
}
This code works without using crypto-pouch well, but if I insert the _db.crypto(...) no data is shown in my list. Can anyone help me? Thanks in advance!
I'm guessing that your put is happening before the call to crypto has finished. Remember, javascript is asynchronous. So wait for the crypto call to finish before putting your design doc. And then use a callback to access your database after it's all finished. Something like the following:
function initDB(options) {
_db = new PouchDB('myDatabase', {adapter: 'websql'});
if (!_db.adapter) {
_db = new PouchDB('myDatabase');
}
_db.crypto(password)
.then(function(){
// add a design document
_db.put(allTypeOne).then(function (info) {
options.success(_db);
})
.catch(function (err) { console.error(err); options.error(err)})
.catch(function (err) { console.error(err); options.error(err);})
}
}
initDB({
success:function(db){
db.query....
}
)

Unable to retrieve records from database

I'm trying to retrieve a record with this:
var users = User.find({ username: "andy" }).then(function(users){
return users;
});
console.log(users);
return res.send(users);
But I get returned:
{
"isFulfilled": false,
"isRejected": false
}
Try writing your code like this, based on the waterline examples:
Users.find({username:'andy'}).exec(function(err, result) {
if (err) {
return res.send(500, {error: err});
}
return res.json(result);
});
The console.log() is outside the then() statement hence it's being executed before User.find() completes and all you get is an unfulfilled promise (not the query results). Try:
var users = User.find({ username: "andy" }).then(function(users){
console.log(users);
res.send(users);
return users;
});

Sails inconsistent record creation

I use the following piece of code to create some records. If I provide incorrect values, say(password and passwordConfirmation does not match), then sometimes an institute record is created without a rollback and sometimes, rollback happens properly.
I would appreciate any help. Is there a better way to do this?
create: function (req, res) {
User.query("BEGIN TRANSACTION", function(result){
if(result) {
sails.log.info(result);
return res.serverError(result);
} else {
Institute.create({
name: req.param('name'),
shortName: req.param('shortName'),
phoneNumber: req.param('phoneNumber'),
subdomain: req.param('subdomain'),
managerEmail: req.param('email')
}, function(error, institute){
if(error) {
sails.log.info(error);
Institute.query("ROLLBACK", function(result) {
sails.log.info(result);
return res.badRequest(error);
});
} else {
User.create({
email: req.param('email'),
password: req.param('password'),
passwordConfirmation: req.param('passwordConfirmation'),
account: institute.id
}, function(error, user) {
if(error) {
sails.log.info(error);
Institute.query("ROLLBACK", function(result) {
sails.log.info(result);
return res.badRequest(error);
});
} else {
User.query("COMMIT", function(result){
sails.log.info(result);
return res.created(user);
});
}
});
}
});
}
});
}
You have a few of options, in no particular order.
1. Write a function that makes all the possible security checks before creation occurs, or use the beforeCreate life cycle call for your models.
For example, you could write a function verifyParams(params) that makes checks such as password comparison (and any other checks you want) for your user creation parameters before you create the institution, or you could just include these checks in your institution creation's beforeCreate method.
2. Delete if there is an error during your user creation
Delete theInstitute model instance in your error case of user creation:
...
User.create(..., function (error, user) {
if (error) {
Institute.destroy(institute.id, function instDestroyed(err) {
...
});
} else {
...
}
});
3. Create a user in your institute model's beforeCreate method.
module.exports = {
attributes: { ... },
beforeCreate: function(values, next) {
User.create(..., function (err, user) {
if (err) { return next(err) }
return next();
});
}
}
Personally, I use method #2 in my own apps.

Conditional Mongoose Query

I have a query that I want to run with a where case, only if a variable is false. This is what I'm doing now, but it's not optimal. Is there a way to do this with one query?
if (user) {
models.Interviews.find({}).exec(function (err, interviews) {
// stuff
});
} else {
models.Interviews.find({}).where('group').equals(group_id).where('disabled').equals(false).exec(function (err, interviews) {
// stuff
});
}
If by 'not optimal' you're referring to needing to duplicate the 'stuff' code without a function, you can build up your Query object in steps like this:
var query = models.Interviews.find({});
if (!user) {
query = query.where('group').equals(group_id).where('disabled').equals(false);
}
query.exec(function (err, interviews) {
// stuff
});
Why is this not optimal? How would a single (more complicated) query be better?
What is not so nice is the duplicated "stuff", but you can easily fix that:
var stuff = function(err, interviews) {
// stuff
};
if (user) {
models.Interviews.find({}).exec(stuff);
} else {
models.Interviews.find({})
.where('group').equals(group_id).where('disabled').equals(false)
.exec(stuff);
}
or
var query = models.Interviews.find({});
if (!user){
query = query.where('group').equals(group_id)
.where('disabled').equals(false);
}
query.exec(function(err, interviews) {
// stuff
});