Skip to content

fix(core): derive possible null value in rxResource stream params (#6…#68171

Open
surajy93 wants to merge 1 commit intoangular:mainfrom
surajy93:fix-core-null-rxresource
Open

fix(core): derive possible null value in rxResource stream params (#6…#68171
surajy93 wants to merge 1 commit intoangular:mainfrom
surajy93:fix-core-null-rxresource

Conversation

@surajy93
Copy link
Copy Markdown

When an optional params function returns undefined, Angular's rxResource internally defaults the params loader value to null at runtime. This change updates ResourceLoaderParams<R> to correctly allow null alongside the resolved type, ensuring developers get accurate TypeScript feedback when omitted.

Fixes #62724

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.dev application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

When the params option is not provided to rxResource or it evaluates to undefined, the type of the params argument in the internal stream function is restricted to the strictly inferred type (e.g. Params), even though it resolves to null at runtime.

Issue Number: #62724

What is the new behavior?

The type inference for ResourceLoaderParams<R> correctly derives a potential null value in instances where undefined could be inferred from the original params option payload. This correctly aligns the TypeScript expectations within stream or loader functions to match the runtime behavior.

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

N/A

@google-cla
Copy link
Copy Markdown

google-cla bot commented Apr 13, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@pullapprove pullapprove bot requested a review from atscott April 13, 2026 16:31
@angular-robot angular-robot bot added the area: core Issues related to the framework runtime label Apr 13, 2026
@ngbot ngbot bot added this to the Backlog milestone Apr 13, 2026
resource({
params,
loader: async ({params}) => `got: ${params.x}`,
loader: async ({params}) => `got: ${params!.x}`,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still not an acceptable solution.
The type shouldn't show up as nullable if the param isn't.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks i will fix it

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kindly review again please @JeanMeche

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't close the PR checking the test cases why it is falling because locally it is working fine.
if you are closing please provide something so that next time i will make sure of that :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AS mentionned in the comments in the issue. The problem also exists on resource().

This comment was marked as off-topic.

Copy link
Copy Markdown
Author

@surajy93 surajy93 Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please review again now fixed the resource too @JeanMeche

@surajy93 surajy93 requested a review from JeanMeche April 13, 2026 17:42
@JeanMeche
Copy link
Copy Markdown
Member

JeanMeche commented Apr 13, 2026

It looks better.
Another example that still doesn't work:

const data = resource({
  params: () => Math.random() ? undefined : 'test',
  loader: ({ params }) => {
    console.log('> params', params); // string, should be string|undefined 
    return Promise.resolve('');
  },
});

@surajy93
Copy link
Copy Markdown
Author

surajy93 commented Apr 13, 2026

It looks better. Another example that still doesn't work:

const data = resource({
  params: () => Math.random() ? undefined : 'test',
  loader: ({ params }) => {
    console.log('> params', params); // string, should be string|undefined 
    return Promise.resolve('');
  },
});

It looks better. Another example that still doesn't work:

const data = resource({
  params: () => Math.random() ? undefined : 'test',
  loader: ({ params }) => {
    console.log('> params', params); // string, should be string|undefined 
    return Promise.resolve('');
  },
});

let me check and test it please provide all the test cases and details thank you

@JeanMeche
Copy link
Copy Markdown
Member

Also please check the CLA check. You're authoring your commits with 2 different names.

@surajy93
Copy link
Copy Markdown
Author

surajy93 commented Apr 13, 2026

const data = resource({
  params: () => Math.random() ? undefined : 'test',
  loader: ({ params }) => {
    console.log('> params', params); // string, should be string|undefined 
    return Promise.resolve('');
  },
});

@JeanMeche

loader should stay typed as string here, not string | undefined. When a params function is provided, Angular treats undefined as “no request” and leaves the resource idle, so the loader is not invoked for that branch. In other words, params() may return string | undefined, but loader only runs for the resolved, non-undefined case. The nullable case we’re fixing is different: it applies when the params option itself is omitted or explicitly undefined, because Angular uses an internal null sentinel there.`

Shorter version:

I don’t think this one should widen to \string | undefined. If params()returnsundefined, the resource goes idle and loaderis skipped, so insideloader the type should remain the non-undefined branch (string). The bug we’re fixing is the separate case where the paramsoption is omitted or explicitlyundefined, which currently flows a runtime null sentinel.

please comment or suggestion why do u think that it should be string |undefined?

@surajy93 surajy93 force-pushed the fix-core-null-rxresource branch 3 times, most recently from 15f8fcc to 6ee7218 Compare April 13, 2026 20:00
…r#68167)

Align resource and rxResource typings with the runtime null sentinel when params are omitted or explicitly undefined.
@surajy93 surajy93 force-pushed the fix-core-null-rxresource branch from 6ee7218 to df0e61a Compare April 13, 2026 20:14
@google-cla google-cla bot added cla: yes and removed cla: no labels Apr 13, 2026
@surajy93
Copy link
Copy Markdown
Author

surajy93 commented Apr 13, 2026

@JeanMeche apart the this edge cases everything look fine can you please take a look

@JeanMeche
Copy link
Copy Markdown
Member

Yeah you're right, my bad for that bad example.

Something else.
The generics are somehow not ideal.

In your test you have:

    const res = resource<string, string>({
      loader: async ({params}) => {
        seenParams = params;
        return 'foo';
      },
      injector: TestBed.inject(Injector),
    });

which should arguably have a single generic (since the request is not defined).

    const res = resource<string>({
      loader: async ({params}) => {
        seenParams = params;
        return 'foo';
      },
      injector: TestBed.inject(Injector),
    });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: core Issues related to the framework runtime cla: yes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rxResource params field type in stream function doesn't derive possible null value

2 participants