st_clair_clarke
st_clair_clarke

Reputation: 5715

Creating a reusable loader for angular v19 resource API with 2 request parameters of different types

Below is the code that creates an angular19 reusable resource loader and its usage with a single request parameter:

import { ResourceLoaderParams } from "@angular/core";

function todoLoader({ request: todoId, abortSignal }: ResourceLoaderParams<number>): Promise<Todo> {
    return fetch(
      `https://jsonplaceholder.typicode.com/todos/${todoId}`, 
      { signal: abortSignal } 
    ).then((res) => res.json() as Promise<Todo>);
}

todoResource = resource({ request: this.todoId, loader: todoLoader });

My difficulty is that I cannot find a way to have two (2) request parameters. I would like to add a second parameter 'appName' of type 'string' to the request parameter.

Appreciate your help

Upvotes: 1

Views: 109

Answers (1)

Naren Murali
Naren Murali

Reputation: 57986

We can define a type for request params, then we can convert the function to return a loader function, which will process the params.

Also we can pass an object to the resource API and pass to the API.

Full Code:

import {
  Component,
  resource,
  ResourceLoader,
  ResourceLoaderParams,
  signal,
} from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
export interface TodoLoaderRequest {
  todoId: number;
  appName: string;
}
export interface Todo {
  id: number;
}
function todoLoader(): ResourceLoader<Todo, TodoLoaderRequest> {
  return ({
    request: { todoId, appName },
    abortSignal,
  }: ResourceLoaderParams<TodoLoaderRequest>) =>
    fetch(
      `https://jsonplaceholder.typicode.com/todos/${todoId}?appName=${appName}`,
      { signal: abortSignal }
    ).then((res) => res.json() as PromiseLike<Todo>);
}

@Component({
  selector: 'app-root',
  template: `
        <a target="_blank" href="https://angular.dev/overview">
          Learn more about Angular
        </a>
      `,
})
export class App {
  todoId = signal(1);
  appName = signal('test');
  todoResource = resource<Todo, TodoLoaderRequest>({
    request: () => ({
      todoId: this.todoId(),
      appName: this.appName(),
    }),
    loader: todoLoader(),
  });
}

bootstrapApplication(App);

Stackblitz Demo

Upvotes: 0

Related Questions