0.0.1 • Published 2 years ago

@mmuscat/angular-swr v0.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

Angular SWR

Data fetching for Angular 14+

Usage

Create a service that fetches data

const endpoint = "https://jsonplaceholder.typicode.com/todos"

@Injectable({ providedIn: "root" })
export class Fetcher implements Fetchable<Todo[]> {
   private http = inject(HttpClient)
   
   fetch(userId: string) {
      return this.http.get(endpoint, { params: { userId }})
   }
}

Create a resource

import { createResource, revalidateOnFocus, revalidateOnInterval, revalidateOnReconnect } from "@mmuscat/angular-swr"

export const TODOS = createResource(Fetcher, {
   features: [
      revalidateOnFocus,
      revalidateOnReconnect,
      revalidateOnInterval(60_000)
   ]
})

Provide and use resource in component

import { TODOS } from "./resource"

@Component({
   selector: "app-todos",
   templateUrl: "./todos.component.html",
   providers: [TODOS],
})
export class TodosComponent {
   protected todos = inject(TODOS)
   
   @Input()
   userId: string
   
   ngOnChanges() {
      this.todos.fetch(this.userId)
   }
}

Read values in template

<!-- todos.component.html -->
<div *ngIf="todos.error">
   Something went wrong
   <button (click)="todos.revalidate()">Retry</button>
</div>
<spinner *ngIf="todos.pending"></spinner>
<todo *ngFor="let todo of todos.value" [value]="todo"></todo>

Options

export interface ResourceOptions {
   providedIn?: Type<any> | "root" | "platform" | "any" | null
   immutable?: boolean
   timeoutMs?: number
   dedupeMs?: number
   refetchIfStale?: boolean
   serialize?: (...params: any[]) => string
   features?: ResourceFeatureWithOptions<{}>[]
}
propertydefaultdescription
providedInnullConfigure which module the resource is provided in
immutablefalsePrevent refetching a resource that is already cached with the given params
timeoutMs3000How long a resource should wait after fetching without receiving a response before it is marked as slow
dedupeMs2000How long a resource should wait before allowing a duplicate fetch with the same params
revalidateIfStaletrueControl whether a resource should revalidate when mounted if there is stale data
serializeJSON.stringifySerializer used to stringify fetch parameters
featuresvoidA list of ResourceFeatureWithOptions that add additional behaviours to the resource

Adding Features

Resource behavior can be customised by adding features.

revalidateOnFocus

Revalidate a resource every time the current page receives window focus.

revalidateOnReconnect

Revalidate a resource every time the network connection comes back online.

revalidateOnInterval

Revalidate a resource periodically according to a timer.

Writing Custom Features

Create a class that implements the ResourceFeature interface.

interface ResourceFeature<T extends {}> {
   onInit?(resource: Resource, options: T): void
   onConnect?(resource: Resource, options: T): void
   onDisconnect?(resource: Resource, options: T): void
   onDestroy?(resource: Resource, options: T): void
}

Example

import { createFeature, Fetchable, Resource, ResourceFeature } from "@mmuscat/angular-swr"

interface LoggerOptions {
   token?: Type<{ log: (resource: Resource) => void }>
}

@Injectable({ providedIn: "root" })
export class Logger implements ResourceFeature<LoggerOptions> {
   private injector = inject(INJECTOR)

   onInit(resource: Resource<T>, { token }: LoggerOptions) {
      const logger = this.injector.get(token, console)
      resource.subscribe(() => {
         logger.log(resource)
      })
   }
}

export function logger(token: Type<any>) {
   return createFeature(Logger, { token })
}

Usage

@Injectable({ providedIn: "root" })
class MyLogger {
   log(resource: Resource) {
      // log implementation
   }
}

const RESOURCE = createResource(Fetcher, {
   features: [
      logger(MyLogger)
   ]
})