Skip to content
This repository was archived by the owner on Jun 16, 2021. It is now read-only.

Latest commit

 

History

History
932 lines (539 loc) · 29.6 KB

model.md

File metadata and controls

932 lines (539 loc) · 29.6 KB

redux-data-service > Model

Class: Model

Model

The Model class is a helper for working with data associated to a DataService.

Immutability

Properties on the Model should use the @attr decorator for specifying fields specific to the Model's own data. It is these values which will be sent to/from the API via the DataService when the Model is instantiated or saved.

Since the DataService is tied to Redux, and data in Redux must be immutable, this class is immutable. However, it will use a magic setter on each decorated field which will dispatch a Redux action to the DataService's reducer. When the reducer receives the value for the new field, a new instance of the Model will be stored and the current Model instance will be marked for destruction. Thus, we preserve the nature of an immutable architecture, with the convenience of a traditional MVC framework.

Decorators

@attr

Use this decorator to specify which properties on the model are a part of the model's own data, which will be sent to/from the API. It takes a FieldType, from which we can determine the property's default value, default validation rules and how to render it dynamically. You may optionally provide a second parameter, to specify a different default value for the property being decorated. To set additional validation rules for the property, use the @validation decorator or one of its variants, such as @required.

@validation

Use this decorator to specify additional validation rules on the property being decorated. Should be used in conjunction with @attr. The format of the object passed into the decorator should match the validation rules for Validate.JS.

@required

Use this decorator as a convenience for setting a validation rule to specify that a property is required.

@belongsTo

Use this decorator to specify a relationship to another Model such that this Model has one of the related Model. For example:

@belongsTo()
organization: IOrganization;

The above example will use the property name to identify the name of the related field's service (which can be specified as the first parameter). It will use a standard naming convention to identify the name of the field on this Model for identifying the ID of the related model to load, in this case it would look for a field named "organizationId" to load the related IOrganization from the "organization" DataService. The relatedFieldName can be specified as the second parameter.

The DataService will return an Observable which will provide new copies of the related Model every time it is updated. If the related Model has not been loaded yet, the DataService will load it and return a "shadow" object while it is loading.

@hasMany

Use this decorator to specify a relationship to another Model such that this Model has many of the related Model. It behaves the exact same as the @belongsTo decorator, except it assumes the relatedFieldName is pluralized and it returns arrays of the related Model instead.

Type parameters

Hierarchy

Model

FakeModel

Implements

Index

Constructors

Properties

Accessors

Methods


Constructors

constructor

new Model(modelData: * Partial<T> & object*, meta?: Partial<IModelMeta<T>>, relatedModels?: IModelsMap): Model

Defined in Model/Model.ts:105

Parameters:

Name Type Default value
modelData Partial<T> & object -
Default value meta Partial<IModelMeta<T>> {}
Default value relatedModels IModelsMap {}

Returns: Model


Properties

dateDeleted

● dateDeleted: Date

Implementation of IModel.dateDeleted

Defined in Model/Model.ts:84


dateUpdated

● dateUpdated: Date

Implementation of IModel.dateUpdated

Defined in Model/Model.ts:81


fields

● fields: IModelKeys< T & any, IFieldType<any>>

Implementation of IModel.fields

Defined in Model/Model.ts:73


id

● id: string

Implementation of IModel.id

Defined in Model/Model.ts:78


<Protected> meta

● meta: IModelMeta<T>

Defined in Model/Model.ts:104


<Protected> modelData

● modelData: Partial<T>

Defined in Model/Model.ts:103


parentIdFieldName

● parentIdFieldName: string

Implementation of IModel.parentIdFieldName

Defined in Model/Model.ts:93


parentServiceName

● parentServiceName: any

Implementation of IModel.parentServiceName

Defined in Model/Model.ts:90


<Protected> relatedModels

● relatedModels: IModelsMap

Defined in Model/Model.ts:105


relationships

● relationships: object

Implementation of IModel.relationships

Defined in Model/Model.ts:75

Type declaration


serializeThroughParent

● serializeThroughParent: boolean

Implementation of IModel.serializeThroughParent

Defined in Model/Model.ts:87


serviceName

● serviceName: string

Implementation of IModel.serviceName

Defined in Model/Model.ts:72


validationRules

● validationRules: IModelKeys<T>

Implementation of IModel.validationRules

Defined in Model/Model.ts:74


Accessors

errors

geterrors(): objectseterrors(value: object): void

Defined in Model/Model.ts:664

Get the list of errors, which may have been created from calling this.validate() or as a response from the API.

Returns: object

Defined in Model/Model.ts:673

Dispatch an action to Redux to set the error state of the Model.

Parameters:

Name Type Description
value object

Returns: void


hasUnsavedChanges

gethasUnsavedChanges(): boolean

Defined in Model/Model.ts:704

Determine if the model or its previously loaded relationships have unsaved changes.

Returns: boolean


isDestroying

getisDestroying(): boolean

Defined in Model/Model.ts:591

Determine if the current instance of the Model has been marked for destruction. That is, this instance is being removed from the Redux store and its subscriptions are being torn down.

Returns: boolean


isDirty

getisDirty(): boolean

Defined in Model/Model.ts:682

Determine if the Model's data has changed without being saved.

Returns: boolean


isLoading

getisLoading(): booleansetisLoading(value: boolean): void

Defined in Model/Model.ts:635

Determine if the Model is currently loading.

Returns: boolean

Defined in Model/Model.ts:644

Dispatch an action to Redux to set the isLoading state of the Model

Parameters:

Name Type Description
value boolean

Returns: void


isNew

getisNew(): boolean

Defined in Model/Model.ts:715

Determine if the Model is a new object which has not been committed to the API yet.

Returns: boolean


isShadow

getisShadow(): boolean

Defined in Model/Model.ts:654

Determine if the Model is a "shadow" object: its data is currently being loaded and this instance of the Model is used as a temporary placeholder until we get a response from the API.

Returns: boolean


parentModelId

getparentModelId(): anysetparentModelId(value: any): void

Defined in Model/Model.ts:95

Returns: any

Defined in Model/Model.ts:99

Parameters:

Name Type
value any

Returns: void


Methods

applyUpdates

applyUpdates(changes?: Partial<T>, meta?: Partial<IModelMeta<T>>, relatedModels?: any): IModel<T>

Implementation of IModel.applyUpdates

Defined in Model/Model.ts:351

Since this class is meant to be immutable, you can apply new updates here. The changes will be deep merged with the existing modelData and/or meta, and a new instance of the class will be returned with those values without mutating the current instance of the class.

Note that this is applied locally. Chances are you will want to dispatch an action instead, via one of the magic setters (so your components will know to update).

Parameters:

Name Type Default value
Default value changes Partial<T> {}
Default value meta Partial<IModelMeta<T>> {}
Default value relatedModels any {}

Returns: IModel<T>


<Protected> checkFieldUpdateIsAllowed

checkFieldUpdateIsAllowed(key: any, value: any): void

Defined in Model/Model.ts:408

Throw a TypeError if the provided key is an invalid fieldType, or the value is an invalid type for that fieldType.

Parameters:

Name Type Description
key any -
value any

Returns: void


delete

delete(): Promise<IModel<T>>

Defined in Model/Model.ts:286

Dispatch an action to Redux to delete the Model

Returns: Promise<IModel<T>>


forceReload

forceReload(): void

Implementation of IModel.forceReload

Defined in Model/Model.ts:334

Dispatch an action to the DataService to force it to reload the model from the API.

Returns: void


getField

getField(fieldName: string, defaultValue?: any): any

Defined in Model/Model.ts:391

This method is called by the magic getters for the properties decorated by the @attr decorator. The actual data for the decorated properties is stored in modelData.

Parameters:

Name Type Description
fieldName string -
Optional defaultValue any -

Returns: any


getFieldError

getFieldError(fieldName: any): any

Defined in Model/Model.ts:726

Parameters:

Name Type
fieldName any

Returns: any


getRelated

getRelated(fieldName: string): any

Defined in Model/Model.ts:450

This method is called by the magic getters for the properties decorated by the @belongsTo and @hasMany decorators.

It will use the relationship definition created by the decorator to grab the DataService of the related field and return an Observable which provides the corresponding item or items.

If the content has not been loaded yet, the DataService will dispatch an action to load the data.

Parameters:

Name Type Description
fieldName string -

Returns: any


getServiceForRelationship

getServiceForRelationship(relationshipKey: string): DataService<any>

Implementation of IModel.getServiceForRelationship

Defined in Model/Model.ts:551

Get the DataService associated to the relationship specified at the given name of the related field

Parameters:

Name Type Description
relationshipKey string -

Returns: DataService<any>


<Protected> getValidationRulesForField

getValidationRulesForField(fieldName: any): any

Defined in Model/Model.ts:275

Get the validationRules for the given fieldName. Works with local or nested fields.

Parameters:

Name Type Description
fieldName any -

Returns: any


getWillDestroyObservable$

getWillDestroyObservable$(): Observable<boolean>

Defined in Model/Model.ts:601

Subscribe to this Observable to be notified when the current instance of the Model has been marked for destruction. That is, this instance is being removed from the Redux store and its subscriptions are being torn down.

Returns: Observable<boolean>


initializeNewModel

initializeNewModel(): void

Implementation of IModel.initializeNewModel

Defined in Model/Model.ts:379

This is a useful hook for doing model-specific initialization when creating a new, unsaved model, such as creating related Models and setting default session values.

Returns: void


isFieldDirty

isFieldDirty(fieldName: * keyof T | string*): boolean

Implementation of IModel.isFieldDirty

Defined in Model/Model.ts:691

Determine if a specific model field of the Model's data has changed without being saved.

Parameters:

Name Type
fieldName keyof T | string

Returns: boolean


markForDestruction

markForDestruction(): void

Implementation of IModel.markForDestruction

Defined in Model/Model.ts:575

Call this method just before this Model instance will be removed from the Redux store. This allows us to cleanly unsubscribe to any relationship Observables that were previously subscribed to, in order to avoid a possible memory leak.

Returns: void


original

original(): this

Implementation of IModel.original

Defined in Model/Model.ts:720

Create a clone of the model without any of the unsaved changes

Returns: this


parseFieldValue

parseFieldValue(fieldName: string, value: any): Promise<any>

Implementation of IModel.parseFieldValue

Defined in Model/Model.ts:739

Given a fieldName as a deep path (such as "firstName" or "person.firstName"), this will use that field's own IFieldType.normalize function to parse the given value.

Parameters:

Name Type
fieldName string
value any

Returns: Promise<any>


reset

reset(): void

Implementation of IModel.reset

Defined in Model/Model.ts:306

Dispatch an action to Redux to reset the Model to its original state. Note: new items will be removed from the Redux store.

Returns: void


save

save(progressSubscriber?: Subscriber<any>): Promise<IModel<T>>

Implementation of IModel.save

Defined in Model/Model.ts:129

Dispatch an action to Redux to commit the pending changes to the API.

Returns a promise which resolves with the new Model on success, or the error response on failure. If there were no changes, it will resolve immediately with the current instance of the Model.

Will reject with validation errors if model is invalid.

Parameters:

Name Type
Optional progressSubscriber Subscriber<any>

Returns: Promise<IModel<T>>


saveModel

saveModel(progressSubscriber?: Subscriber<any>): Promise<IModel<any>>

Implementation of IModel.saveModel

Defined in Model/Model.ts:158

Dispatch an action to Redux to commit the pending changes to the API for just this model, without first saving any related models with pending changes (unless they're serialized with this model).

Returns a promise which resolves with the new Model on success, or the error response on failure.

If this model was loaded initially as a nested model, and the parent is marked to serialize this model, then saving this model will instead save the parent model.

Note that this method does not validate the model or check if it has pending changes. You probably want to use the save() method instead.

Parameters:

Name Type
Optional progressSubscriber Subscriber<any>

Returns: Promise<IModel<any>>


saveRelatedModels

saveRelatedModels(): Promise<IModel<T>[]>

Implementation of IModel.saveRelatedModels

Defined in Model/Model.ts:195

Dispatch an action to Redux to commit the pending changes to the API for any of the related models which have already been loaded and would not be serialized when this model is saved. After each model is saved, its new copy is set onto a new copy this model.

Returns a promise which resolves with each of the new models.

Note that this method does not validate the related models before it saves them.

Returns: Promise<IModel<T>[]>


setField

setField(fieldName: string, value: any): void

Defined in Model/Model.ts:430

This method is called by the magic setters for the properties decorated by the @attr decorator.

Since this class is meant to be immutable, attempting to set on a property will actually dispatch an action to Redux, where a new instance of the Model will be created and stored.

The current instance of the Model will not be mutated!

Parameters:

Name Type Description
fieldName string -
value any

Returns: void


setMetaField

setMetaField(fieldName: any, value: any): void

Defined in Model/Model.ts:621

This method is called by the magic setters for some of the meta properties.

Since this class is meant to be immutable, attempting to set on a property will actually dispatch an action to Redux, where a new instance of the Model will be created and stored.

Parameters:

Name Type Description
fieldName any -
value any

Returns: void


setRelated

setRelated(fieldName: string, value: any): void

Defined in Model/Model.ts:521

This method is called by the magic setters for the properties decorated by the @belongsTo and @hasMany decorators.

Since the class is meant to be immutable, the related item or items will not be set directly on this instance. Instead, the magic setter for the related field on this class (which tracks the relationship) will be called with the ID or IDs of the value provided, which will dispatch an action to the DataService.

Parameters:

Name Type Description
fieldName string -
value any

Returns: void


<Protected> triggerWillDestroyObservable

triggerWillDestroyObservable(): void

Defined in Model/Model.ts:564

This is an internal method which will tell the WillDestroyObservable to emit a value

Returns: void


unload

unload(): void

Implementation of IModel.unload

Defined in Model/Model.ts:323

Dispatch an action to Redux to remove this Model from its data store.

Returns: void


validate

validate(includeRelatedModels?: boolean): IModelKeys<T>

Defined in Model/Model.ts:221

Perform client-side validation on the Model based on the validationRules as defined by property decorators. The validation results will be returned immediately and dispatched to Redux.

We currently use Validate.JS as our validation library.

If includeRelatedModels is set to true, any related model on this model which has been loaded previously will be validated as well. The keys for the validation results of nested models will be flattened with "." separator

Parameters:

Name Type Default value Description
Default value includeRelatedModels boolean false -

Returns: IModelKeys<T>


validateField

validateField(fieldName: any): any

Defined in Model/Model.ts:251

Perform client-side validation on the Model based on the validationRules as defined for the given fieldName. The field's validation results will be returned immediately and dispatched to Redux.

Note: this works with nested paths (such as "person.firstName") in addition to fields local to the model.

Parameters:

Name Type Description
fieldName any -

Returns: any