
Product
A New Design for GitHub PR Comments
We redesigned our GitHub PR comments to deliver clear, actionable security insights without adding noise to your workflow.
@modelata/angular-fire
Advanced tools
modelata-angular-fire is a wrapper of @angular/fire with firestore for angular application modelata-angular-fire implement and extend modelata-fire
modelata-angular-fire gives abstract class and abstract dao to be extend.
Angular | Firebase | AngularFire | @modelata/fire | @modelata/angular-fire |
---|---|---|---|---|
15 | 9.18 | ^7.5 | ^5.0.0 | ^8.0.0 |
13 | 9.6 | ^7.2 | ^4.0.0 | ^7.2.0 |
A model/class describes a type of document stored in Firestore.
Modelata adds the following features to it:
Modelata provides the following "CRUD" functions to manipulate easily documents stored in Firestore:
This Modelata service makes it easy to manage the current authenticated user:
export class UserModel extends MFModel<UserModel> {
name?: string = null;
constructor(
data: Partial<UserModel>,
mustachePath: string,
location: Partial<IMFLocation>,
) {
super();
super.initialize(data, mustachePath, location);
}
}
its possible to add attributes in the model
attributes prefixed with _ will not be saved in database attributes that are observables must be suffixed by $
export class UserModel extends MFModel<UserModel> {
_notSavedInDb: number = null;
notSavedInDb$: Observable<any> = null;
_notSavedInDb$: Observable<any> = null;
savedInDb: number = null;
// ...
}
modelata-angular-fire set some attribute an all models.
modelata-angular-fire give some decorator for your model attributes.
@SubCollectionGetList<M = any>(collectionName: string, daoName: string, options?: IMFGetListOptions<M>)
Decorator to use on a model property. Its value will then be an observable of the list of documents present in the specified collection.
/!\ to use this Decorator, you must inject the dao as a dependency in your model's constructor. /!\
/!\ keep in mind that dependency injection is one way only and avoid injecting parents'dao in children models /!\
export class UserModel extends MFModel<UserModel> {
@SubCollectionGetList('subCollectionName', '_subUserDAOService')
_subUserCollectionDocs$: Observable<SubUserCollectionDocModel[]> = null;
@SubCollectionGetList('subCollectionName', 'subUserDAOService', {
orderBy: {
field: 'myDate',
operator: 'asc',
},
})
_subUserCollectionDocsSorted$: Observable<SubUserCollectionDocModel[]> = null;
constructor(
data: Partial<UserModel>,
mustachePath: string,
location: Partial<IMFLocation>,
protected _subUserDAOService: SubUserDAOService, // dao attribute name must be start with an underscore, else the DAO try to save it in database (cf prefix/suffix)
) {
super();
super.initialize(data, mustachePath, location);
}
}
@GetByRef(attributeName: string, daoName: string)
Decorator to use on a model property. Its value will then be an observable of the document referenced by the linked attribute.
/!\ to use this Decorator, you must inject the dao as a dependency in your model's constructor. /!\
export class UserModel extends MFModel<UserModel> {
@GetByRef('myRefDoc', '_myRefDAOService')
_myRef$: Observable<RefDocModel> = null;
myRefDoc: DocumentReference = null;
constructor(
data: Partial<UserModel>,
mustachePath: string,
location: Partial<IMFLocation>,
protected _myRefDAOService: MyRefDAOService, // dao attribute name must be start with an underscore, or else the DAO will try to save it in database (cf prefix/suffix)
) {
super();
super.initialize(data, mustachePath, location);
}
}
For GetByRef AND SubCollectionGetList. add MyRefDAOService via getNewModel method of UserDaoService
export class UserDaoService extends MFFlattableDao<UserModel> {
constructor(
db: AngularFirestore,
storage: AngularFireStorage,
protected myRefDAOService: MyRefDAOService, // Dependency injection
) {
super(db, storage);
}
getNewModel(
data?: Partial<UserModel>,
location?: Partial<IMFLocation>,
): UserModel {
const userModel = new UserModel(
data,
this.mustachePath,
location,
this.myRefDAOService,
); // add myRefDAOService for GetByRef AND SubCollectionGetList.
return userModel;
}
}
@InSubDoc(subDocPath: string)
Decorates a property that is constructed by DAO with the value of the same property of a subdocument.
/!\ the dao must be extend 'MFFlattableDao' (not MFDao).
export class UserModel extends MFModel<UserModel> {
@InSubDoc('protectedData/private')
phone: Observable<RefDocModel> = null;
// ....
}
@StorageProperty(options: IMFStorageOptions)
Decorates a property that is a file to save in firebase Storage. The property must be of type : IMFFile.
@StorageProperty({
deletePreviousOnUpdate: false,
deleteOnDelete: true
})
picture: IMFFile = null;
MFModel give two public methods toFormBuilderData
(and toString).
we have four decorators for add any validators on model attribute or add/remove attributes control.
Returns data to build a form group
'blur' // all control on blur
{
anwser:'blur'
name:'change'
} // each control with his value, other to default
{
default:'blur',
except:{
name:'change'
}
} // all control to blur except name on change
// myComponent.component.ts
this.myFormGroup = this.angularFormBuilder.group(
myModel.toFormBuilderData({ phone: true }, 'blur', { anwser: sectionModel }),
);
@FormControlValidators(value?: ValidatorFn[])
Adds validators to form control when generating form group data
@FormControlValidators([Validators.minLength(2)])
public name: string = null;
@NotInFormControl()
Explicitly DOES NOT generates form control for this property
@ToFormControl()
Generates form control for this property (ex: for a private attribute)
@ToFormGroupFunction(fn: function(value,options: AbstractControlOptions,speacialData:any))
Generates specific form group data with the given function
@ToFormGroupFunction<AnswerModel>((defaultValue?: any, options: AbstractControlOptions = {}, sectionModel?: SectionModel) => {
if (!options.validators) {
options.validators = [];
}
if (sectionModel && sectionModel.textMaxLength) {
(options.validators as ValidatorFn[]).push(Validators.maxLength(sectionModel.textMaxLength));
}
if (sectionModel && sectionModel.textMinLength) {
(options.validators as ValidatorFn[]).push(Validators.minLength(sectionModel.textMinLength));
}
return [defaultValue, options];
})
answer: string = null;
@Injectable({
providedIn: 'root',
})
@CollectionPath('/users')
export class UserDaoService extends MFDao<UserModel> {
constructor(db: AngularFirestore, storage: AngularFireStorage) {
super(db, storage);
}
getNewModel(
data?: Partial<UserModel>,
location?: Partial<IMFLocation>,
): UserModel {
const userModel = new UserModel(data, this.mustachePath, location);
return userModel;
}
}
getNewModel methode is used by MFDao, MFFlattableDao and by your components/service for instanciate a new model. If you want to add data calculated from existing data (or any data that is not in database) to your models, this is the method to do it.
beforeSave methode is called by MFDao or MFFlattableDao on all model just before saving it to the database. If you want delete field or add calculated data, this is the method to do it.
beforeSave(dataReadyToSave, idOrLocation){
if (dataReadyToSave.birthdate){
dataReadyToSave.age = dataReadyToSave.birthdate.toAge();
delete dataReadyToSave.birthdate;
}
return dataReadyToSave;
}
@CollectionPath('/users')
CollectionPath decorator must be used on all DAO. CollectionPath take in parameter a string representing the collection path in firestore db. If the collection is a subcollection (collection in a document), use the "mustache" syntaxe for all document id.
@CollectionPath('/users/{userId}/mySubCollection/{mySubDocId}/subSubcollection')
All methods that need an id or a location (like "get"), now take a Location with ids mentioned in CollectionPath.
const location = {
id: 'mySubSubDocId',
mySubDocId: 'id',
userId: 'id',
};
@DeletionMode(MFDeleteMode.SOFT)
DeletionMode decorator is used for set the deletion strategy for this DAO. (default : HARD) DeletionMode take in parameter a enum value MFDeleteMode.SOFT or MFDeleteMode.HARD. MFDeleteMode.SOFT :
get(idOrLocation: string | IMFLocation, options?: IMFGetOneOptions)
Get a model from database from id or location
export interface IMFGetOneOptions {
/**
* Document will include an hidden property containing document snapshot
*/
withSnapshot?: boolean;
/**
* Observable returned will complete on first result
*/
completeOnFirst?: boolean;
/**
* Request result will be cached in order to get a faster answer on same getOne request
*/
cacheable?: boolean;
/**
* Display an error in console when requested document not exists (default: true)
*/
warnOnMissing?: boolean;
}
getByReference(reference: DocumentReference, options?: IMFGetOneOptions)
Get a model from database from its reference
getByPath(path: string, options?: IMFGetOneOptions)
Get a model from database from its path
getList(location?: MFOmit<IMFLocation, "id">, options?: IMFGetListOptions<M>)
Get a list of documents in the collection
export interface IMFGetListOptions<M> {
/**
* Documents will include an hidden property containing document snapshote
*/
withSnapshot?: boolean;
/**
* Observable returned will complete on first result
*/
completeOnFirst?: boolean;
/**
* Where conditions
*/
where?: IMFWhere[];
/**
* Order by
*/
orderBy?: IMFOrderBy;
/**
* Maximum result returned
*/
limit?: number;
/**
* boundary of the get, only one is applied
*/
offset?: IMFOffset<M>;
/**
* Request result will be cached in order to get a faster answer on same getList request
*/
cacheable?: boolean;
}
getModelFromSnapshot(snapshot: DocumentSnapshot, options?: Partial<IMFGetOneOptions>)
get a model from a snapshot
getListByPath(path: string, options?: IMFGetListOptions<M>)
Get list of document by collection path
update(data: Partial<M>, location?: string | IMFLocation | M, options?: IMFUpdateOptions<M>)
update some field of a model.
/**
* List of file properties of the model M for which stored files MUST (true) or MUST NOT be deleted on document update
* (Overrides behaviour configured in model decorators)
*/
export type IMFDeletePreviousOnUpdateFilesOptions<M extends IMFModel<M>> = {
/**
* File property : true => the previous file will be deleted if updated
* File property : false => the fprevious ile will NOT be deleted if updated
*/ [fileAttribute in NonFunctionPropertyNames<M>]?: boolean;
};
/**
* Options to pass to update method
*/
export interface IMFUpdateOptions<M extends IMFModel<M>> {
deletePreviousOnUpdateFiles?: IMFDeletePreviousOnUpdateFilesOptions<M>;
}
create(data: M, location?: string | Partial<IMFLocation>, options?: IMFSaveOptions)
save a new model in db, update if already exist.
export interface IMFSaveOptions {
/**
* If document already exists, it will be fully overwritten
*/
overwrite?: boolean;
}
delete(idLocationOrModel: string | IMFLocation | M, options?: IMFDeleteOptions<M>)
Delete a model by id
/**
* List of file properties of the model M for which stored files MUST (true) or MUST NOT be deleted on document deletion
* (Overrides behaviour configured in model decorators)
*/
export declare type IMFDeleteOnDeleteFilesOptions<M extends IMFModel<M>> = {
/**
* File property : true => the file will be deleted
* File property : false => the file will NOT be deleted
*/
[fileAttribute in NonFunctionPropertyNames<M>]?: boolean;
};
/**
* Options to pass to delete method
*/
export interface IMFDeleteOptions<M extends IMFModel<M>> {
deleteOnDeleteFiles?: IMFDeleteOnDeleteFilesOptions<M>;
cascadeOnDelete?: boolean;
mode?: MFDeleteMode; // used for override defaultvalue (HARD or @DeletionMode)
}
deleteByReference(reference: AngularFirestoreDocument<M>)
Delete a model by its reference
getReference(idOrLocationOrModel: string | Partial<IMFLocation> | M)
Get a reference from an id, a location or directly from model
getReferenceFromPath(path: string)
Get a reference from a compatible path
getSnapshot(idOrLocation: string | IMFLocation, options?: IMFGetOneOptions)
Get a document snapshot from database from an id or a location
isCompatible(doc: M | DocumentReference | CollectionReference)
Check if the model or reference is compatible with this DAO based on its path
with modelata-angular-fire, all database request result are cached with a bypass ( like behaviorSubject )
all current cached results are automatically destroyed on auth user logout.
MFCache.setClearAllCacheObservable(clearAllCacheAndSubscription$: Observable<any>)
dao class decorator Tells the DAO to NOT cache the result
@DisableCache // without '()'
export class UserDaoService extends MFDao<UserModel>
method decorator Tells the Dao to cache request results
export class UserDaoService extends MFDao<UserModel> {
// ...
@Cacheable
public getFooByBar(): Observable<Foo> {
// return myObservable
}
}
FAQs
@modelata/fire implementation for angular 15
The npm package @modelata/angular-fire receives a total of 20 weekly downloads. As such, @modelata/angular-fire popularity was classified as not popular.
We found that @modelata/angular-fire demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
We redesigned our GitHub PR comments to deliver clear, actionable security insights without adding noise to your workflow.
Product
Our redesigned Repositories page adds alert severity, filtering, and tabs for faster triage and clearer insights across all your projects.
Security News
Slopsquatting is a new supply chain threat where AI-assisted code generators recommend hallucinated packages that attackers register and weaponize.