Skip to main content

Class: Model<T, R>

Defined in: model/model.ts:9

Document class represents a database document and provides useful methods to work with.

Example

import { connect, model } from "ottoman";
connect("couchbase://localhost/travel-sample@admin:password");

// Create an `User` model
const User = model('User', { name: String });

// Create a document from the `User` Model
const jane = new User({ name: "Jane Doe" })

Extends

Type Parameters

T

T = any

R

R = any

Accessors

$isNew

Get Signature

get $isNew(): boolean

Defined in: model/document.ts:615

Boolean flag specifying if the document is new.

Example
const CardSchema = new Schema({
cardNumber: { type: String, immutable: true },
zipCode: String,
});

// Create model
const Card = model('Card', CardSchema);

// Create document
const myCard = new Card({ cardNumber: '4321 4321 4321 4321', zipCode: '43210' });
myCard.$isNew; // true

// Save document
const myCardSaved = await myCard.save();
myCardSaved.$isNew; // false
Returns

boolean

Inherited from

Document.$isNew

Methods

_applyData()

_applyData(data, strategy): Model<T, R>

Defined in: model/document.ts:524

Allows to easily apply data from an object to current document.

Parameters

data

any

strategy

ApplyStrategy = true

Returns

Model<T, R>

Examples

const user = new User({ name: "John Doe" });

user._applyData({ name: "Jane Doe" });
console.log(user) // { name: "Jane Doe" }
const User = model('Card', { name: { type: String, immutable: true } });
const user = new User({ name: 'John Doe' });

// with strategy:false is like above example
user._applyData({ name: 'Jane Doe' }, false);
console.log(user); // { name: "Jane Doe" }

// with strategy:true remains immutable
user._applyData({ name: 'Jane Doe' }, true);
console.log(user); // { name: "John Doe" }

// trying to update it directly
user.name = 'Jane Doe';
console.log(user); // { name: "John Doe" }

// with strategy:CAST_STRATEGY.THROW
user._applyData({ name: 'Jane Doe' }, CAST_STRATEGY.THROW);
// ImmutableError: Field 'name' is immutable and current cast strategy is set to 'throw'

Inherited from

Document._applyData


_depopulate()

_depopulate(fieldsName): Model<T, R>

Defined in: model/document.ts:440

Reverts population. Switches back document reference.

Parameters

fieldsName

string | string[]

Returns

Model<T, R>

Example

To get in context about the Card and Issue Models see the populate example..

const card = await Card.findById(cardId);
console.log(card.issues); // ['issueId']

await card._populate('issues')
console.log(card.issues); // [{ id: 'issueId', title: 'Broken card' }]

card._depopulate('issues')
console.log(card.issues); // ['issueId']

Inherited from

Document._depopulate


_getId()

_getId(): string

Defined in: model/document.ts:124

Returns id value, useful when working with dynamic ID_KEY.

Returns

string

Example

  console.log(user._getId()); // 'userId'
console.log(user.id); // 'userId'

Inherited from

Document._getId


_getIdField()

_getIdField(): string

Defined in: model/document.ts:131

Returns id key.

Returns

string

Inherited from

Document._getIdField


_populate()

_populate(fieldsName?, options?): Promise<Model<T, R>>

Defined in: model/document.ts:418

Allows to load document references.

Parameters

fieldsName?

PopulateFieldsType

options?

PopulateOptionsType

Returns

Promise<Model<T, R>>

Example

Getting context to explain populate.

// Defining the schemas
const addressSchema = new Schema({
address: String,
});
const personSchema = new Schema({
name: String,
age: Number,
address: { type: addressSchema, ref: 'Address' },
});
const companySchema = new Schema({
president: { type: personSchema, ref: 'Person' },
ceo: { type: personSchema, ref: 'Person' },
name: String,
workers: [{ type: personSchema, ref: 'Person' }],
});

// Initializing the models
const Address = model('Address', addressSchema);
const Person = model('Person', personSchema);
const Company = model('Company', companySchema);

// Adding some data
const johnAddress = await Address.create({ address: '13 Washington Square S, New York, NY 10012, USA' });
const john = await Person.create({ name: 'John Smith', age: 52, address: johnAddress });

const janeAddress = await Address.create({ address: '55 Clark St, Brooklyn, NY 11201, USA' });
const jane = await Person.create({ name: 'Jane Doe', age: 45, address: janeAddress });

const company = await Company.create({ name: 'Space X', president: john, ceo: jane });

// Getting saved company data
const spaceX = await Company.findById(company.id);
console.log(`Company: `, company);

Will get:

Company: {
name: 'Space X',
president: '50e85ac9-5b4f-4587-aeb6-b287527794c9',
ceo: '32c2e85a-cc91-4db2-935f-f7d2768168de',
id: 'd59efbdf-4b7e-4d2f-a986-6e8451f22822',
_type: 'Company'
}

Now we will see how the _populate methods works.

const result = await spaceX._populate('ceo');
console.log(`Result: `, result);
Result: {
name: 'Space X',
president: '50e85ac9-5b4f-4587-aeb6-b287527794c9',
ceo: {
name: 'Jane Doe',
age: 45,
address: '235dd441-b445-4b88-b6aa-2ce35a958a32',
id: '32c2e85a-cc91-4db2-935f-f7d2768168de',
_type: 'Person'
},
id: 'd59efbdf-4b7e-4d2f-a986-6e8451f22822',
_type: 'Company'
}

Can also pass an array or a string separated by a comma

const result = await spaceX._populate('ceo,president');
// or
const result = await spaceX._populate(['ceo', 'president']);
console.log(`Result: `, result);
Result: {
name: 'Space X',
president: {
name: 'John Smith',
age: 52,
address: 'bc7ea8a8-8d1c-4ab6-990c-d3a0163f7e10',
id: '50e85ac9-5b4f-4587-aeb6-b287527794c9',
_type: 'Person'
},
ceo: {
name: 'Jane Doe',
age: 45,
address: '235dd441-b445-4b88-b6aa-2ce35a958a32',
id: '32c2e85a-cc91-4db2-935f-f7d2768168de',
_type: 'Person'
},
id: 'd59efbdf-4b7e-4d2f-a986-6e8451f22822',
_type: 'Company'
}

If you want to get only a portion of the object

const result = await spaceX._populate({
ceo: ['age', 'address'], // or 'age,addres'
president: 'name',
});
console.log(`Result: `, result);
Result: {
name: 'Space X',
president: { name: 'John Smith' },
ceo: { age: 45, address: '235dd441-b445-4b88-b6aa-2ce35a958a32' },
id: 'd59efbdf-4b7e-4d2f-a986-6e8451f22822',
_type: 'Company'
}

Now let's to go deeper

const result = await spaceX._populate(
{
ceo: {
select: 'age,id', // remember you can use ['age','address']
populate: 'address', // will populate all the fields
},
president: {
select: 'name',
populate: {
address: 'address', // will populate address field only
},
},
},
2, // for populate up to the second level
);
console.log(`Result: `, result);
Result: {
name: 'Space X',
president: {
name: 'John Smith',
address: { address: '13 Washington Square S, New York, NY 10012, USA' }
},
ceo: {
age: 45,
id: '32c2e85a-cc91-4db2-935f-f7d2768168de',
address: {
address: '55 Clark St, Brooklyn, NY 11201, USA',
id: '235dd441-b445-4b88-b6aa-2ce35a958a32',
_type: 'Address'
}
},
id: 'd59efbdf-4b7e-4d2f-a986-6e8451f22822',
_type: 'Company'
}

Below is another way through the find functions

const result = await Company.findOne(
{ name: 'Space X' },
{
select: 'president,ceo',
populate: {
president: { select: 'address,id', populate: 'address' },
ceo: { select: ['age', 'name'], populate: { address: { select: 'id' } } },
},
populateMaxDeep: 2,
},
);
console.log(`Result: `, result);
Result: {
ceo: {
age: 45,
name: 'Jane Doe',
address: { id: '235dd441-b445-4b88-b6aa-2ce35a958a32' }
},
president: {
address: {
address: '13 Washington Square S, New York, NY 10012, USA',
id: 'bc7ea8a8-8d1c-4ab6-990c-d3a0163f7e10',
_type: 'Address'
},
id: '50e85ac9-5b4f-4587-aeb6-b287527794c9'
}
}

Inherited from

Document._populate


_populated()

_populated(fieldName): boolean

Defined in: model/document.ts:480

Allows to know if a document field is populated.

Parameters

fieldName

string

Returns

boolean

Example

To get in context about the Card and Issue Models see the populate example..

const card = await Card.findById(cardId);
console.log(card.issues); // ['issueId']
console.log(card._populated('issues')); // false

await card._populate('issues')
console.log(card.issues); // [{ id: 'issueId', title: 'Broken card' }]
console.log(card._populated('issues')); // true

Inherited from

Document._populated


_validate()

_validate(): any

Defined in: model/document.ts:568

Runs schema validations over current document.

Returns

any

Example

const user = new User( { name: "John Doe" } );

try {
await user._validate()
} catch(errors) {
console.log(errors)
}

Inherited from

Document._validate


remove()

remove(options): Promise<any>

Defined in: model/document.ts:208

Removes the document from the database.

Parameters

options

removeOptions = {}

Returns

Promise<any>

Example

const user = User.findById('userId')

await user.remove();

Inherited from

Document.remove


save()

save(onlyCreate, options): Promise<any>

Defined in: model/document.ts:148

Saves or Updates the document.

Parameters

onlyCreate

boolean = false

options

saveOptions = {}

Returns

Promise<any>

Example

const user = new User({ name: "John Doe" }); //user document created, it's not saved yet

await user.save(); // user saved into the DB

// You also can force save function to only create new Documents by passing true as argument
await user.save(true); // ensure to execute a insert operation

Inherited from

Document.save


toJSON()

toJSON(): Model<T, R>

Defined in: model/document.ts:582

Returns a Javascript object to be serialized to JSON

Returns

Model<T, R>

Inherited from

Document.toJSON


toObject()

toObject(): Model<T, R>

Defined in: model/document.ts:575

Returns a Javascript object with data

Returns

Model<T, R>

Inherited from

Document.toObject