ngx-appwrite
v1.8.1
Published
A wrapper around the Appwrite WebSDK for easier implementation in Angular 16+ projects. The goal is to make the whole SDK accessible as well as provide some convenience functionality like RxJS streams where appropriate.
Readme
ngx-appwrite
A wrapper around the Appwrite WebSDK for easier implementation in Angular 16+ projects. The goal is to make the whole SDK accessible as well as provide some convenience functionality like RxJS streams where appropriate.
Compatibility
| ngx-appwrite | Appwrite-Server | Angular | Appwrite-Web SDK | | ------------ | --------------- | ------- | ---------------- | | 1.8.1 | 1.8.X | 21+ | 21.5.0 | | 1.7.4 | 1.7.X | 19+ | 18.1.1 | | 1.7.0 | 1.6.X | 16+ | 17.0.0 | | 1.6.X | 1.6.X | 16+ | 16.0.0 |
Installation
npm install ngx-appwriteUsage/Examples
1 - The package is using an Angular standalone configuration.
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideAppwrite } from 'ngx-appwrite';
import { SECRETS } from '../secrets.env';
export const appConfig: ApplicationConfig = {
providers: [
provideAppwrite({
endpoint: SECRETS.SERVER_URL,
project: SECRETS.PROJECT_ID,
defaultDatabase: SECRETS.DEFAULT_DATABASE,
}),
],
};Alternative A: Use the appwrite services directly to access the SDK
import { Component, OnInit, inject } from '@angular/core';
import { Account } from 'ngx-appwrite';
@Component({
standalone: true,
imports: [],
selector: 'app-root',
templateUrl: './app.component.html',
styleUrl: './app.component.scss',
})
export class AppComponent implements OnInit {
private account = inject(Account);
// login to appwrite
async ngOnInit() {
// login
const session = await this.account.createEmailPasswordSession(
SECRETS.EMAIL,
SECRETS.PASSWORD,
);
console.log(session);
// provide the prefs structure
const account: Models.User<{ hello: string }> | null = await this.account.get<{ hello: string }>();
console.log(account?.prefs.hello);
// output 'world'
// observable stream on the users auth session
this.account.onAuth$<{ hello: string }>()
.subscribe((account: Models.User<{ hello: string }> | null) => {
console.log(account?.prefs.hello);
});
}
}Alternative B: Use the service adapter to connect to collections
// friends.service.ts
import { Injectable } from '@angular/core';
import { AppwriteAdapter } from 'ngx-appwrite';
import { Input, array, merge, number, object, parse, string } from 'valibot';
// Validation is optional, this example uses Valibot, but you can use any validation library or implement your own logic
// Valibot reference schema for the Appwrite base document
const AppwriteDocumentSchema = object({
$id: string(),
$collectionId: string(),
$databaseId: string(),
$createdAt: string(),
$updatedAt: string(),
$permissions: array(string()),
});
// Valibot schema for friends, merges base document
const friendSchema = merge([
object({
name: string(),
age: number(),
}),
AppwriteDocumentSchema,
]);
// inferred type from Valibot schema
export type Friend = Input<typeof friendSchema>;
@Injectable({
providedIn: 'root',
})
export class FriendsService extends AppwriteAdapter<Friend> {
// required
protected tableId: string = <TABLE_ID>;
// The appwrite adapter implements CRUD operations as well as the ability to validate retrieved data. If the validationFn property is undefined, no validation of incoming data is performed.
protected validationFn = (data: unknown) =>
// validate using Valibot parse method
parse(friendSchema, data);
// AppwriteAdapter provides the following methods
// create
// update
// upsert
// delete
//
// document (Promise)
// document$ (Observable)
// documentList (Promise)
// documentList$ (Observable)
}Use the FriendsService in your component
import { Component, OnInit, inject } from '@angular/core';
import { Account } from 'ngx-appwrite';
import { Friend, FriendsService } from './appwrite.service';
@Component({
standalone: true,
imports: [],
selector: 'app-root',
templateUrl: './app.component.html',
styleUrl: './app.component.scss',
})
export class AppComponent implements OnInit {
private friendsService = inject(FriendsService);
// login to appwrite
async ngOnInit() {
this.friendsService.documentList$().subscribe((list) => {
console.log(
'Friend age:',
list.documents[0].age,
);
console.log(
'Friend name:',
list.documents[0].name,
);
});
await this.friendsService.create({
name: 'Mae Sue',
age: 18,
});
}
}Alternative C: Use the RXDB replication adapter for an offline-first approach.
Make sure you name your Appwrite databases and collections correctly according to the official Docs
// friends.service.ts
import { Injectable } from '@angular/core';
import { AppwriteAdapterWithReplication } from 'ngx-appwrite/replication';
// inferred type from schema
export interface Human {
id: string;
name: string;
age: number;
homeAddress: string;
}
@Injectable({
providedIn: 'root',
})
export class HumansRxdbService extends AppwriteAdapterWithReplication<Human> {
constructor() {
super();
this.startReplication({
rxdbDatabasename: 'mydb',
collectionId: 'humans',
rxdbSchema: {
title: 'humans',
version: 0,
primaryKey: 'id',
type: 'object',
properties: {
id: {
type: 'string',
maxLength: 100,
},
name: {
type: 'string',
},
age: {
type: 'number',
},
homeAddress: {
type: 'string',
},
},
required: ['id', 'name', 'age', 'homeAddress'],
},
});
}
}Use the HumansService in your component
[...]
export class HumanComponent {
private formBuilder = inject(FormBuilder);
private humansService = inject(HumansRxdbService);
humanForm = this.formBuilder.group({
id: [''],
name: ['', Validators.required],
age: [0, Validators.required],
homeAddress: ['', Validators.required],
});
humans$: Observable<RxDocument<Human>[]> = this.humansService.documentList$();
saveHuman(): void {
if (this.humanForm.valid) {
const humanData = this.humanForm.getRawValue();
if (!humanData.id) {
delete (humanData as Partial<Human>).id;
}
this.humansService.upsert(humanData as Human);
this.resetForm();
}
}
editHuman(human: RxDocument<Human>): void {
this.humanForm.patchValue(human.toJSON());
}
deleteHuman(human: RxDocument<Human>): void {
human.remove();
}
resetForm(): void {
this.humanForm.reset({
id: '',
name: '',
age: 0,
homeAddress: '',
});
}
}