How to extend the Schema in Mongoose? - schema

I would like to add a static method to the Schema class, how do I do without changing the main Schema class?
thanks

This is how the website documents it:
// assign a function to the "statics" object of our animalSchema
animalSchema.statics.findByName = function (name, cb) {
this.find({ name: new RegExp(name, 'i') }, cb);
}

Related

How to save object in mongoose

I want to use object to combine admins, but I cant figure out. Here is the schema and code
UserSchema = new mongoose.Schema({
name: { type:String },
owner : {
Admin : mongoose.Schema.Types.ObjectId
}
});
And saving function:
user.name = 'nerkn';
user.owner={ Admin :new ObjectId(Adminid)} // this is from another user
el = req.db.model('Users')(user)
el.save((err)=>{console.log(err)})
console.log('el', el)
when I check name is saved but owner.Admin is not.
You should mark as modified nested objects before save
el.markModified('owner');

GraphQL, Dataloader, [ORM or not], hasMany relationship understanding

I'm using for the first time Facebook's dataloader (https://github.com/facebook/dataloader).
What I don't understand is how to use it when I have 1 to many relationships.
Here it is a reproduction of my problem: https://enshrined-hydrant.glitch.me.
If you use this query in the Playground:
query {
persons {
name
bestFriend {
name
}
opponents {
name
}
}
}
you get values.
But if you open the console log here: https://glitch.com/edit/#!/enshrined-hydrant you can see these database calls I want to avoid:
My Person type is:
type Person {
id: ID!
name: String!
bestFriend: Person
opponents: [Person]
}
I can use dataloader good for bestFriend: Person but I don't understand how to use it with opponents: [Person].
As you can see the resolver has to return an array of values.
Have you any hint about this?
You need to create batched endpoints to work with dataloader - it can't do batching by itself.
For example, you probably want the following endpoints:
GET /persons - returns all people
POST /bestFriends, Array<personId>` - returns an array of best friends matchin the corresponding array of `personId`s
Then, your dataloaders can look like:
function batchedBestFriends(personIds) {
return fetch('/bestFriends', {
method: 'POST',
body: JSON.stringify(personIds))
}).then(response => response.json());
// We assume above that the API returns a straight array of the data.
// If the data was keyed, you could add another accessor such as
// .then(data => data.bestFriends)
}
// The `keys` here will just be the accumulated list of `personId`s from the `load` call in the resolver
const bestFriendLoader = new DataLoader(keys => batchedBestFriends(keys));
Now, your resolver will look something like:
const PersonType = new GraphQLObjectType({
...
bestFriend: {
type: BestFriendType,
resolve: (person, args, context) => {
return bestFriendLoader.load(person.id);
}
}
});

Vue Multiselect: Access object within object for custom option

I am using the Vue Multiselect Custom Option Template
and I want to use the name property as a customLabelnormally this would be easy as just using name but in this case the property I need is within another object.
Here is the object I am bringing in:
0:Object
created_at:null
id:1
profile:Object
id:1
picture_url:"some-image.jpg"
profile_id:"your-id"
profile_name:"Your Name"
profile_id:1
subscription_active:1
updated_at:null
Normally name would be in the root so it would easy to access but I need to access profile_name which is nested under profile
Here's what I have tried so far:
methods: {
customLabel ({ profile['profile_name'] }) {
return `${ profile['profile_name'] }`
}
This will work:
methods: {
customLabel ({ profile }) {
return `${ profile.profile_name }`
}

Is there buttons / funtion calls & tables handled in MetaWidget - js

I am wondering if some can help me out to get the buttons , function calls and tables displayed using metawidget jsonSchema.
Unfortunately, I can see it just as a form render-er for our applications, is it something which we need to define externally? also if we could navigate from one form to another somehow
<script type="text/javascript">
var mw = new metawidget.Metawidget( document.getElementById( 'metawidget' ), {
inspector: new metawidget.inspector.CompositeInspector( [ new metawidget.inspector.PropertyTypeInspector(),
function( toInspect, type, names ) {
return {
properties:
name: {
required: true
},
notes: {
type: "string",
large: true
},
employer: {
type: "string",
section: "Work"
},
department: {
type: "string"
}
}
};
} ] ),
layout: new metawidget.jqueryui.layout.TabLayoutDecorator(
new metawidget.layout.TableLayout( { numberOfColumns: 2 } ))
} );
mw.toInspect = person;
mw.buildWidgets();
Above schema holds only properties to render the fields, but where to specify the functionalities?
Assuming the object you are inspecting has functions, in JSON schema you can specify the property with a type of function. Metawidget will render these as buttons (and will wire up their click handler).
Note that PropertyTypeInspector will find functions automatically, so you could also consider combining your JsonSchemaInspector with a PropertyTypeInspector using CompositeInspector.
Often your data object (e.g. var person = { firstname: 'Homer', surname: 'Simpson' } ) and your actions object (e.g. var personActions = { save: function() {...}, delete: function() {...}} ) are separate. In those cases you can position two Metawidgets as siblings (or nested within each other), each pointing at different objects.
Finally for tables use a type of array. In JSON schema, you nest an items object that further nests a properties object, to describe the properties of the array items. See this example http://blog.kennardconsulting.com/2016/04/metawidget-and-angular-arrays.html (it's for Angular, but the JSON Schema is the same)

Passing parameters to save()

Is it possible to pass parameters like this? I need to pass some information that is not part of the model itself.
myModel.save({site : 23})
You can pass options as of Ember Data 2.2. However, you have to remember to pass your options under the adapterOptions property. For example,
myModel.save({
adapterOptions: {
site: 23
}
});
Inside either of DS.Store#findAll, DS.Store#findRecord, DS.Store#query, DS.Model#save and DS.Model#destroyRecord, one of the parameters should now have adapterOptions. In the case of DS.Model#save, you can override updateRecord in your adapter:
export default DS.Adapter.extend({
updateRecord(store, type, snapshot) {
// will now have `snapshot.adapterOptions`.
// ...
}
});
It is possible if you:
add a 'volatile' attribute to your model,
define a custom model serializer, and override its serializeIntoHash method.
For instance:
App.Model = DS.Model.extend({
//...
site: DS.attr('number', { serialize: false })
});
App.ModelSerializer = DS.RESTSerializer.extend({
serializeIntoHash: function(hash, type, record, options) {
this._super(hash, type, record, options);
Ember.merge(hash, {
'site': record.get('site')
});
}
});
See this comment, this is the correct way to achieve your goal.