Skip to content

Feature Request: Allow calling resource signals directly #63480

@asherwoodcnet

Description

@asherwoodcnet

Which @angular/* package(s) are relevant/related to the feature request?

core

Description

I'm certain this has been considered already, but I couldn't find an issue discussing it or a mention in the resource RFCs, so I apologize if this has been discussed at length.

I'm finding that I consistently write the same boilerplate everywhere I use resources. Almost every time I use a resource I end up writing some version of this computed signal:

readonly fooValue = computed(() => {
  if (this.fooResource.hasValue()) {
    return this.fooResource.value();
  } else if (this.fooResource.error()) {
    return this.fooResource.error();
  } else if (this.fooResource.isLoading()) {
    return "Loading...";
  }
});

Proposed solution

The idea is simple, but the implementation seems thorny. As a baseline, I'm considering that it would be convenient to call a resource directly, with something like the following behavior:

readonly myResource = resource({
  loader: (): Promise<MyType> => ...
});

// calling myResource() directly would be equivalent to calling this computed signal:
readonly myValue = computed<MyType | Error | undefined>(() => {
  if (this.myResource.hasValue()) {
    return this.myResource.value();
  } else if (this.myResource.error()) {
    return error();
  }
  return undefined;
});

It seems clear that there's not a one-size fits all solution to this, so perhaps this merits an additional configuration point on the resource? Something like:

readonly myResource = resource({
  loader: (): Promise<MyType> => ...
  transform: (response: {value?: MyType, status: ResourceStatus, error?: Error, isLoading: boolean}) => {
    if (response.error) {
      return "Something went wrong!";
    } else if (response.isLoading) {
      return "Loading...";
    } else {
      return response.value;
    }
  },
});

Alternatives considered

I've been torn about writing a wrapper, and haven't decided to go that direction yet because I don't really want to diverge from the angular primitives.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: coreIssues related to the framework runtimecore: reactivityWork related to fine-grained reactivity in the core frameworkcross-cutting: resourceIssues related to the newly introduced resource / httpResource

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions