Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 542
AryanJ-NYC Avatar asked Jun 22 '16 13:06

AryanJ-NYC


People also ask

Can Mongoose be used with TypeScript?

Mongoose introduced officially supported TypeScript bindings in v5. 11.0. Mongoose's index.

Is Mongoose schema a class?

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.

What is schema in TypeScript?

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.

What is the difference between mongoose schema and model?

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.


2 Answers

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>
like image 66
DNRN Avatar answered Oct 03 '22 16:10

DNRN


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>;
like image 32
rinukkusu Avatar answered Oct 03 '22 15:10

rinukkusu