Grandjs Framework
GrafkaGrand CliGrand ConnectorsGrand ModelAboutFeaturesPrerequisitesInstallingDependenciesBuilding ModelDefine New ModelDefine a new property inside your modelSettingsPropertyMethodData TypesStringNumberObjectIdObjectArrayAdd Model inside another ModelHow can I use Model inside another Model ?Instantiate ModelValidate ModelAccess Schema ObjectGrand Validator
Grandjs Core
GraphQlIntroduction

Grand Model

About

Grand Schema is a javascript package for building models for your data using typescript, it's available for either frontend or backend developement, it also can be used to validate your models, it's so good to be used in frontend to describe your data how they will be, also it's good for backend if you want to build a project in repository pattern and cleand archeticture.

Features

  • data modeling
  • model schema validation
  • flexible schema
  • mongoose compatiblity
  • typescript compatibility
  • uses decorators for injecting property definition

Prerequisites

  • install nodejs on your machine
  • install typescript
  • initialize a new typescript project

Installing

npm i grand-model

Dependencies

grandjs depends on another package called grand-validator which is a grandjs package that can make validation on the schema you define

Grand Model installs grand-validator by default

Building Model

to build a model firstly, you need to import the following into your ts file:

import {Entity, property, method, settings} from "grand-model"
  • Entity: this is an abstracted class that you will extend to build your model
  • settings: this is a decorator to inject some settings into your model class
  • property: this is a decorator that you will use to inject definition into your model property
  • method: This is a decorator to define some methods inside your model you can use later to inject them inside your mongoose schema or use these methods to perofrm something over the data

Define New Model

To define a new model you need to extend the Entity class as the following:

import {Entity, property, method, settings} from "grand-model"
@settings()
class User extends Entity {
}

Define a new property inside your model

import {Entity, property, method, settings} from "grand-model"
@settings()
class User extends Entity {
@property({required: true | false, type: String, value: })
name:string
}

Settings

settings is a decorator you use to decorate your model to bootstrap it to accept the decorated properties and methods inside it

Property

Property is a decorator that you use to define settings to your model property, this decorator takes one parameter as an object, this object can contain the following properties:

propertytyperequireddefaultdescription
requiredbooleanfalsetruedecide either this property is required when you create new instance from this model or not
typeData Typestrue-define the data type of this model property
messagestring-set custom message to be returned when your model is validated, and the property doesn't match the schema definition
minnumberfalse-set a minimum length for your string or a minimum number for your number
maxnumberfalse-set a maximum length for your string or a maximum number for your number
regexRegExpfalse-set a regex for your string
lengthnumberfalse-set the length of the string characters or aray items

Method

Method is a decorator you use for your model methods to define that this function is a method related to your schema that can perofrm a specific action or execute something Example

import {Entity, method, property, settings} from "grand-model";
@settings()
class User extends Entity{
@property({required: true, type: String})
firstName:string
@property({required: true, type: String})
lastName:string
@method
getFullName() {
return this.firstName + this.lastName
}
}

Data Types

The following table shows the data types that you can use to define your model

String

You can define your model property as a string using one of the following approaches: String, Types.String, "string", "String"

Example

import {Entity, property, settings} from"grand-model"
import {Types} from "grand-validator"
@settings()
class User extends Entity{
@property({required: true, type: String | Types.String | "string" | "String"})
name:string
}

Number

You can define your model property as a Number using one of the following approaches: Number, Types.Number, "number", "Number"

Example

import {Entity, property, settings} from"grand-model"
import {Types} from "grand-validator"
@settings()
class User extends Entity{
@property({required: true, type: Number | Types.Number | "Number" | "number"})
age:number
}

ObjectId

You can define your model property as a ObjectId using one of the following approaches: ObjectId, Types.ObjectId, "ObjectId", "objectId"

Example

import {Entity, property, settings} from"grand-model"
import {Types} from "grand-validator"
@settings()
class User extends Entity{
@property({required: true, type: Types.ObjectId | "ObjectId" | "objectId"})
_id_:string
}

Object

You can define your model property as a Object using one of the following approaches: Object, Types.Object, "Object", "object", {}

Example

import {Entity, property, settings} from"grand-model"
import {Types} from "grand-validator"
@settings()
class User extends Entity{
@property({required: true, type:
Object | Types.Object | "Object" | "object"|
{}
})
activities:Object | {}
}

Array

You can define your model property as a Array using one of the following approaches: Array, Types.Array, "Array", "array", []

Example

import {Entity, property, settings} from"grand-model"
import {Types} from "grand-validator"
@settings()
class User extends Entity{
@property({required: true, type:
Array | Types.Array | "Array" | "array"|
[]
})
activities:Array | []
}

Add Model inside another Model

Grand Model gives you the ability to use a model inside another model which helps you to not repeat your schema definition and also grand model have the ability to validate these nested models

How can I use Model inside another Model ?

You can use a model inside another model for one of the following uses:

  • use a model as a sub model inside an object or as an object
  • use a model as an array of this model inside the other model

Example

import {Entity, property, settings} from"grand-model";
@settings()
class Post extends Entity{
@property({type: String, required:true})
title:string
@property({type:User, required:true})
author:User
}
@settings()
class User extends Entity{
@property({required: true, type: String})
name:string
@property({required: true, type: [Post]})
posts: Post[]
}

In this above example as you can see, we defined to models, the forst one is the post model and the second one is the User Model, these two models have relation together, the post uses one user and the user uses an array of posts once you validate the model it will automatically validate the sub models and returns their validations if there is an error

Instantiate Model

After defining your model, surly you need to instantiate these models and pass data to it, so you can easily instantiate your models as the following:

import {Entity, property, settings} from"grand-model";
@settings()
class Post extends Entity{
@property({type: String, required:true})
title:string
@property({type:User, required:false})
author:User
}
@settings()
class User extends Entity{
@property({required: true, type: String})
name:string
@property({required: true, type: [Post]})
posts: Post[]
}
const user = new User({name: "tarek", posts: [{
title: "test post",
}]})

Validate Model

To validate the model you need to access on a builtin object inside the model called functions this object contains some helper methods, one of them is a function called validate

user.functions.validate();

This function perofrm a validation process on your data based on the defined shcema

To access on the validation result, there is a property called validations, which is an array contains your validations result

user.validations

This array contains objects, each object contains the following:

propertytypedescription
keyNamestringthe name of property that is failed in the validation
messagestringthe returned message if the property is failed in validation
valueTypestringthe data type that this property should be based on the defined schema
currentValueTypestringthe current value of the property

Access Schema Object

to Access the Schema Object of the model you can access on it by accessing a property called Schema

Example

@settings()
class User extends Entity{
@property({required: true, type: String})
name:string
}
const user = new User({name: "tarek"})
// access on the schema
console.log(user.Schema);

you can also access on it from the class itself as the following:

@settings()
class User extends Entity{
@property({required: true, type: String})
name:string
}
// access on the schema
console.log(User.prototype.Schema);