Mongoose validation access siblings - javascript

Consider the case:
validatedSchema = new schema({
id : "1454216545154",
name: { type: Number, validate: [
function(v){
return (this.id !== Server.LoggedIn.ID);
}, 'Don't try to change the name of another user!!!!'
]}
})
I haven't yet set up my full server for testing but am in planning stage.
Can we access sibling elements from the validation function, in this case 'id' and 'external' variables? And if so, how?
Thank you

No, you can't. But what you're looking to do here is really access control which doesn't belong in your ORM layer anyway.
But if you really wanted to do this, you could add pre-save middleware to check that the current user can only save changes to their own record:
validatedSchema.pre('save', function (next) {
if (this.id !== Server.LoggedIn.ID) {
next(new Error("Can't change another user's data!"));
} else {
next();
}
});

Related

pouchdb put is still rejected with _rev

I'm using pouchDB for the first time, and as indicated in the docs I'm using put() so it will automatically handle revisions. However, when the code is running and there's an existing item with the same ID, it's still rejecting even when including a _rev.
Here's my code:
var db = new PouchDB('blog')
...
function saveCategory(category) {
var savedCategory = {
_id: 'category' + category.id,
_rev: '2-' + String(new Date().toISOString()),
name: category.name,
nicename: category.slug,
post_count: category.count,
description: category.description,
link: category.link,
parent: category.parent
}
return db.put(savedCategory).then((response) => {
$log.log(response)
}).catch((error) => {
$log.error('error saving category ',error)
})
}
This is not the purpose of the _rev field. It is always generated by the server and not by your code. To update a document you must pull the entire document (including the _rev field), update the desired fields, and then put the document. The value of _rev should be the same as when you got it from the server.
If you have a new record, you do not need to set _rev.
The pocketDB guide has a very useful section about this.

How to add a complex object to model of each angular-formy type when validated?

Say I have a custom angular-formly type that extends a input type.
Lets call it user.
Before the form gets filled in model = {}.
Once its filled in and valid, I would like to have this result
model = {
user:{
name:"TestName" //The value of the input
someCustomData: "Not part of the form"
someMoreMetaData: "Also not part of the from"
}
}
The resulting model having appended arbitrary meta-data once user entered a valid name. Thus creating a "user specific model"
So basically, I want my validation function to push the result to the model.
How would I approach this, for the key has to be bound to a property of a object that will only exist once validation returns true.
{
key: //what do I bind to?
type: 'USER',
templateOptions: {
required: true,
type: 'text'
},
validators:{
isValid: function($viewValue, $modelValue, scope){
var value = $modelValue || $viewValue;
if (validateName(value)){
scope.model.user = { name: viewValue, date:....}
return true;
}
}
}
}
If possible, please nudge me in the right direction..Still pretty novice.
$scope.user
{
'name':'TestName',
'someCustomData': 'Not part of the form',
'someMoreMetaData': 'Also not part of the from'
}
You should add a watch validation and act when valid:
scope.$watch('myForm.myInput.$valid', function(validity) {$scope.user.custom data ="blabla"})

Meteor User table value axtracting

How do I pick the email address value from meteor Mongo user table?
I have written below query to pick the element:
users=Meteor.users.find({},{emails:1})
This the code I have written to fetch the email address, but I don't know how much it's affecting performance in the code:
users = Meteor.users.find({})
users.forEach(function(key,option){
key.emails.forEach(function (key,option){
console.log(key.address)
});
});
In meteor, you should call:
users = Meteor.users.find({}, { fields: { emails: 1 } })
Reference in docs
EDIT
Please remember users is a cursor object. Cursor objects can be handled directly in templates, and must be the return of publications. You can't iterate a cursor directly in a javascript loop.
Example: (remember authorization in production publications)
Meteor.publish('user-emails', function() {
return Meteor.users.find({}, { fields: { emails: 1 } });
});
If you want to directly access the user instances, for example to iterate them in a javascript code, you need to fetch the cursor (reference in docs).
Example:
var users = Meteor.users.find({}, { fields: { emails: 1 } }).fetch();
Now users is an array of users. Feel free to iterate them.
Example (I'm using underscore.js):
var users = Meteor.users.find({}, { fields: { emails: 1 } }).fetch();
_.each(users, function(user) {
console.log(user.emails);
});
Now, if you need a vector only with emails, one on each index, you can pluck the emails from a fetched array with underscore.js (reference of pluck)
var emails = _.pluck(Meteor.users.find({}, { fields: { emails: 1 } }).fetch(), 'emails');
Hope it works :)
if its not working, dont forget to return
return users

sails.js beforeCreate method receives only the model properties on which required is set to true

This is a model in sails.js.
module.exports = {
attributes: {
name: {
type: "string"
},
email: {
type: "email",
required: true
},
password: {
type: "string"
}
},
beforeCreate: function(values, next) {
console.log(values); //logs {email:"mail#someplace.com"}
console.log(values.email); // logs the email id sent via post
console.log(values.password); // logs undefined is required is set to false, If required is set to true, password will log properly.
next();
}
};
I am planning to perform some encrypting of the password in the beforeCreate function, Of course I will be requiring the password and can continue with it right now but how to manage this for optional values just in case the need arises?
I found the reason for the above issue,
In my controller, I was doing a create record but the record I was creating contained only one field, i.e the email see below:
Users.create({email:req.body.email}).exec(function(err, user){
// user created
});
The model is directly mapped with the object being inserted into the database, So internally sails removes/ignores the fields which are not present.
To not remove these empty fields, you might have to set schema:true in your model.

How bind search values in mongodb with mongoose

I have the following code in my /search/:query route:
var param = {
query: req.query['query']
}
MyModel.find({
"$or": [
{ 'name': req.param.query },
{ 'age': req.param.query },
{ 'event': req.param.query },
]
}, function (err, results) {
if (err) {
console.log(err)
}
else {
res.render('index', {
data: results
});
}
}
);
And is good, i can search for pretty much every data that i want, but only individually. What if i want search name + age, can i? Example: 'Leo 22'.
There is any way that mongoose help me with this?
UPDATE:
My problem is:
I have tables lists it titles, this title is the concatenation of 'eventName' and 'eventDate'.
Real examples of this fields:
'Special Event - 20/12/2015'
'Classic Event - 12/03/2015'
'Hot Summer Event - 05/07/2005'
Every week will be create 4 events. In some point, a user will search for an old event, and i believe that the user will search in this format:'EVENT NAME - EVENT DATE'..
So i need a way to bind this values in my controllers.
I'm no familiar with mongoose but in order to do that, you must have a way to bind your query param to the attribute you want to search. Otherwise, they wouldn't know Leo is name and 22 is age.
Ur path would be like search?name=:name&age=:age&event=:event and in your code, you will have to process like if the param is not null, add and condition to it.
It seems you are using only one parameter (req.param.query) to filter all attributes. That's not mongoose related: you could create distinct parameters for each attribute and pass them along the query string.
For instance:
"$or": [
{ 'name': req.param.name },
{ 'age': req.param.age },
{ 'event': req.param.event },
]
And your HTTP request will be like this:
http://youraddress/expressRoute?name=Leo&age=22

Categories

Resources