I'm writing a simple web application using Angular 2 written in TypeScript. MongoDB is my database on a Mongoose framework while running on a Node server on an Express framework. My MongoDB and Node code is written in vanilla JS.
Now, I created a Mongoose model for a Country as following:
"use strict";
const Schema = require('mongoose').Schema,
db = require('../../config/database');
let countrySchema = new Schema({
countryName: { type: String, index : { unique : true } }
});
let Country = db.model('Country', countrySchema);
module.exports = Country;
Now, Country is what I want my object to be. In my app component, I have:
import { Component } from '@angular/core';
import { CountryService } from '../services/country.service';
import { Country } from '../models/country.model';
@Component({
selector: 'my-app',
templateUrl: 'app/views/app.component.html',
providers: [ CountryService ]
})
export class AppComponent {
originCountries: Country[];
destinationCountries: Country[];
constructor(private countryService: CountryService) { };
ngOnInit() {
this.getCountries();
}
getCountries() {
this.countryService.getCountries()
.then(countries => {
this.originCountries = countries;
this.destinationCountries = countries;
});
}
}
See how originCountries and destinationCountries should be arrays of Countries? I can't just import Country from the Country model (even though it sounded right in my head at the time).
What is the best way to create a country class that is based on the Mongoose model?
Mongoose introduced officially supported TypeScript bindings in v5. 11.0. Mongoose's index.
Mongoose allows us to create schema from an ES6 class. The loadClass() method provided by Mongoose Schemas takes in a class object as input and copies all methods, statics, and getters/setters of the class into the Schema object.
A Schema represents an ECSchema in TypeScript. It is a collection of Entity-based classes. See the BIS overview for how ECSchemas are used to model information. ECSchemas define classes for models, elements, and aspects, as well as ECRelationships.
Mongoose Schema vs. Model. A Mongoose model is a wrapper on the Mongoose schema. A Mongoose schema defines the structure of the document, default values, validators, etc., whereas a Mongoose model provides an interface to the database for creating, querying, updating, deleting records, etc.
You use an interface like this ICountry:
export interface ICountry {
_id: string;
name: string;
}
You can now use this interface in your mongoose setup:
import mongoose = require('mongoose');
import { ICountry } from './interfaces';
var _schema: mongoose.Schema = new mongoose.Schema({
name: { type: String, required: true, index: { unique: true } }
});
type CountryType = ICountry & mongoose.Document;
var _model = mongoose.model <CountryType> ('Country', _schema);
export class Country {
static getAll(): Promise<Array<ICountry>> {
return new Promise<ICountry> ((resolve, reject) => {
_model.find((err, counties) => {
err ? reject(err) : resolve(counties);
});
});
}
}
And the route setup:
var router = express.Router();
router.get('/api/countries', (req, res) => {
Country.getAll().then(c => {
return res.json(c);
});
});
And implement it in your Angular application, if you need some methods or just import the interface direct in your service class:
import { ICountry } from '../../interfaces';
...
countries: Array<ICountry>
This is how I do it in my project:
In my schema file:
///<reference path="../typings/mongoose/mongoose.d.ts"/>
import * as mongoose from 'mongoose';
var UserSchema = new mongoose.Schema({
name: String,
// ...
});
export interface IUser extends mongoose.Document {
_id: string;
name: string;
// ...
}
export interface IUserModel extends mongoose.Model<IUser> { }
export var User: IUserModel = <IUserModel>mongoose.model<IUser>('User', UserSchema);
In the server side code:
import {User, IUser, IUserModel} from '../schemas/user.schema';
// ...
User.findOne({ ... });
In the client side code I now can use the IUser
interface:
import {IUser} from '../---/schemas/user.schema';
// ...
userCache: Array<IUser>;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With