BooG690 BooG690 - 5 months ago 118
Node.js Question

Representing Mongoose model as a Typescript class

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?

Answer

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>