Given a MEVN stack using Nestjs, MongoDB(mongoose) I am working to setup server-side pagination. My approach is to use the mongoose-aggregate-paginate-v2, but I have not been able to distill what I need from my research1 to make this work within the framework of Nestjs(typescript) and mongoose. Thanks for the assist..
Following documentation on Nestjs mongoose models, and mongoose-aggregate-paginate-v2 setup, I have the following:
contact.provider.ts
import mongoose, { Connection, AggregatePaginateResult, model } from "mongoose";
import { ContactSchema } from "./contact.schema";
import aggregatePaginate from "mongoose-aggregate-paginate-v2";
import { IContact } from "./interfaces/contact.interface";
// notice plugin setup:
ContactSchema.plugin(aggregatePaginate);
// is this correct ?
interface ContactModel<T extends Document> extends AggregatePaginateResult<T> {}
// how to create model for factory use ?
export const ContactModel: ContactModel<any> = model<IContact>('Contact', ContactSchema) as ContactModel<IContact>;
export const contactProvider = [
{
provide: 'CONTACT_MODEL',
useFactory: (connection: Connection) => {
// how to instantiate model ?
let model = connection.model<ContactModel<any>>('Contact', ContactSchema);
return model;
},
inject: ['DATABASE_CONNECTION'],
},
];
I am between reading the Nestjs documentation, mongoose documentation, and typescript documentation. Somewhere along this path there is a way to provide the aggregatePaginate method on my Contact model, so that I can call like:
contact.service.ts
// Set up the aggregation
const myAggregate = this.contactModel.aggregate(aggregate_options);
const result = await this.contactModel.aggregatePaginate(myAggregate, options); // aggregatePaginate does not exist!
Review code in progress - available on this branch.
Research
Mongoose the Typescript way…?
Complete Guide for using Typescript in Mongoose with lean() function
Complete guide for Typescript with Mongoose for Node.js
MosesEsan/mesan-nodejs-crud-api-with-pagination-filtering-grouping-and-sorting-capabilities
Node.js API: Add CRUD Operations With Pagination, Filtering, Grouping, and Sorting Capabilities.
API Paging Built The Right Way
SO: Mongoose Plugins nestjs
SO: Pagination with mongoose and nestjs
There is a conflict between NestJs and mongoose-aggregate-paginate-v2 and mongoose-paginate-v2 because those plugins are using #types/mongoose, so, NestJS has conflicts if you use #types/mongoose.
I tell you this because i was trying the same thing and figure it out that is not posible to implement mongoo-aggreate-paginate-v2/mongoose-paginate-v2 till Nestjs solve the issues with #types/mongoose.
I can recommend you make a custom function by your own to do that or use https://www.npmjs.com/package/mongoose-paginate because that plugin does not require #types/mongoose.
Related
We have a basic app state that needs to be persisted upon the browser refresh. similar to vuex-state-persistance plugin. Here is the basic state code that needs to be persisted.
export const initialState = {
user: {
uuid: 'wedRfertYjsnjnakUiisdj878HBhsns',
name: 'Kiran Maniya',
scope: 'user'
}
};
Is there anything that can be used directly as a plugin or I need to write a custom plugin that persists the state in localStorage asynchronously? Also, how do we modularise the state when we have a complex and large state to manage?
Aurelia Store provides a built-in mechanism to persist state in localStorage.
So, if your initialState goes initialized in main.ts or main.js something like this:
aurelia.use.plugin('aurelia-store', { initialState: initialState });
Then in app.ts or .js you should register the localstorage middleware and perform a rehydration.
So, in app constructor, you could write:
import { localStorageMiddleware, rehydrateFromLocalStorage, Store } from 'aurelia-store';
import { initialState, State } from 'state';
...
constructor(
private store: Store<State>,
) {
store.registerMiddleware(localStorageMiddleware, MiddlewarePlacement.After, { key: ¨someKey¨ });
store.registerAction('Rehydrate', rehydrateFromLocalStorage);
}
Regarding modularization, maybe you should combine store and the EventAggregator to implement more complex scenarios.
Good luck
I am creating a reactive application with Meteor (with MongoDB as a backend).
I initially created a non-reactive-aware collection and denormalizers, eg.:
class DocCollection extends Mongo.Collection {
insert(doc, callback) {
const docId = super.insert(doc, callback);
doc = docMongo.findOne(docId); // for illustration, A
console.log(doc);
return docId;
}
}
docMongo = new DocCollection();
Now, I'd like to wrap it into MongoObservable, which will facilitate listening to the changes to the collection:
export const Doc = new MongoObservable.Collection(docMongo);
Then, I define a Method:
Meteor.methods({
add_me() {
Doc.insert(myDoc);
}
});
in server/main.js and call it in app.component.ts's constructor:
#Component(...)
export class AppComponent {
constructor() {
Meteor.call('add_me');
}
}
I get undefined printed to console (unless I sleep a little before findOne), so I suppose when I was looking for the doc after insertion in my Mongo.Collection, the document wasn't yet ready to be searched for.
Why does it happen, even though I overwrote the non-reactive class and only then wrapped it in MongoObservable?
How do I typically do denormalization with a reactive collection? Should I pass observables to my denormalizers and there create new ones, or is it possible to nicely wrap the non-reactive code afterwards (like I tried and failed above)? Note that I don't want to directly pass doc inside, as in more complex scenarios it will cause other inserts/updates elsewhere for which I'd also want to wait.
How do people typically test these things? If I run a test, the code above may succeed locally, as db insertion time is small, but fail when the delay is higher.
I have the following model:
import { Model } from '#vuex-orm/core'
export class User extends Model {
static entity = 'users'
static fields () {
return {
id: this.attr(null),
name: this.attr('')
}
}
}
and when I try to do this:
User.insert({
data: { id: 1, name: 'John' }
})
I get the following error:
Uncaught (in promise) TypeError: Class constructor User cannot be invoked without 'new'
Any idea what is the problem? This code is from the documentation, so I'm confused a little bit.
as I can see you are missing the registration of the model in the database at the beginning of the application.
You have to implement your vuex store with the corresponding plugin
EXAMPLE:
import Vue from 'vue'
import Vuex from 'vuex'
import VuexORM from '#vuex-orm/core'
import User from '#/models/User'
import Post from '#/models/Post'
Vue.use(Vuex)
// Create a new instance of Database.
const database = new VuexORM.Database()
// Register Models to Database.
database.register(User)
database.register(Post)
// Create Vuex Store and register database through Vuex ORM.
const store = new Vuex.Store({
plugins: [VuexORM.install(database)]
})
export default store
You now have good documentation in this regard
I hope I have helped you, greetings
I'm trying to use the npm package 'vuex-orm-decorators' from https://github.com/scotley/vuex-orm-decorators#readme
When I try to insert into the DB, I get the error TypeError: this.types is not a function
Entity looks like this
import { Model } from "#vuex-orm/core";
import { NumberField, OrmModel, StringField } from "vuex-orm-decorators";
#OrmModel("races")
export default class Race extends Model {
#NumberField()
public ID!: number;
#StringField()
public Name!: string;
}
store looks like this:
import Vue from "vue";
import Vuex from "vuex";
import { ORMDatabase } from "vuex-orm-decorators";
Vue.use(Vuex);
export default new Vuex.Store({
.
.
.
plugins: [ORMDatabase.install()]
});
Also, maybe this is a clue.... in Vuex-Orm, this.setters is returning a value, but this.setters('all') is returning undefined.
/**
* Get all records.
*/
Model.all = function () {
return this.getters('all')();
};
From seeing the undefined basic fields and functions, it seems like the vuex-orm database isn't getting set up correctly. Any ideas?
I tried to create a stackoverflow tag for vuex-orm-decorators, but I'm not quite at 1500 rep yet, so I just tagged it as vuex-orm.
There is a small bug in vuex-orm-decorators package in the implementation of the types function defined in Vuex-ORM Single Table Inheritance docs.
I've created a fork in which I fixed this simple problem and created a pull request to update the original package.
Lastly, I've to point that from my tiny dive into this package that it isn't fully ready yet for table inheritance features built in Vuex-ORM but still is great for simple use cases.
I would like to use sails.io.js with angular5, so I used angular2-sails module. I managed to connect angular to sails but I didn't manage to retrieve the events from sails.js, for example when a new document is created in database. Is there something to configure sails side ? I used this.sailsService.on("user").subscribe(data => console.log("event on user")). The get and post methods are perfectly working. Sails side I put
ioclient: require('socket.io-client')('http://localhost:1337'),
io: require('sails.io.js'),
In config/http.js, instead of
var io = require('sails.io.js')( require('socket.io-client') );
because else sails cannot load
I didn't write anything in config/socket.js
angular2-sails module is deprecated so I used the io variable from sails.io.js using a service :
import {Injectable} from '#angular/core';
function _window(): any {
// return the global native browser window object
return window;
}
#Injectable()
export class SocketService {
get ioSails(): any {
return _window().io;
}
}