Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fetch from lazy-query strategy returns undefined instead of a promise #44

Closed
lukascivil opened this issue May 10, 2022 · 8 comments
Closed

Comments

@lukascivil
Copy link

lukascivil commented May 10, 2022

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

When using fetch with the lazy query strategy, undefined is returned. If we use unwrap() from fetch, we will get an exception because fetch returns undefined when it should return a promise to be resolved.

useLazyGetHymnResumeQuery = useLazyGetHymnResumeQuery()

function buttonClick() {
   // Does nothing
    this.useLazyGetHymnResumeQuery.fetch('1')

  //1- A strategy to understand what's going on
   const value1 = await this.useLazyGetHymnResumeQuery.fetch('1')
  
  // Prints undefined, but it should print Promise()....
   console.log(value1)  

  // 2- Another strategy to understand what's going on
   const value2 = await this.useLazyGetHymnResumeQuery
 
 // Prints Correctly, proves that fetch exists and is a method
 // fetch: () => ...
 // lastArg$: ...
 // state$: ...
   console.log(value2)  
}

Expected behavior

In the previous topic I basically performed some testing strategies but, I believe that the fetch is not working properly, returning a promise.

useLazyGetHymnResumeQuery = useLazyGetHymnResumeQuery()

function buttonClick() {
   // Dispatch an action and return a promise with .unwrap()
    this.useLazyGetHymnResumeQuery.fetch('1')
}

Minimal reproduction of the problem with instructions

  1. User clicks the button
  2. The buttonClick() method is called
  3. useLazyGetHymnResumeQuery.fetch('1') does nothing

What is the motivation / use case for changing the behavior?

I'm trying to implement a manual call through RTK, so I need to call when the user clicks on a button in the App. And the lazy query strategy is not working correctly, I believe it's a problem with the fetch that doesn't return a promise and doesn't dispatch an action. The most interesting thing is that normal query (like use...Query) works without any problem.

Environment

Development, testing the tool


Angular version: ~13.2.2


Browser:
- [x] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: v16.14.2
- Platform:  Windows 

Others:
Sorry for the console tests, it was a way I had to test the tool with my app.
@SaulMoro
Copy link
Owner

SaulMoro commented May 11, 2022

The 'fetch' function is to execute the query, you can see a guide at https://github.com/SaulMoro/ngrx-rtk-query#lazy-queries

Also example of its use in https://github.com/SaulMoro/ngrx-rtk-query/blob/master/src/app/features/lazy/lazy-counter/lazy.component.ts#L72

Example:

this.countQuery
      .fetch(id, { preferCacheValue })
      .unwrap()
      .then((result) => {
        console.log('result', result);
        this.form.reset();
      })
      .catch(console.error);

@lukascivil
Copy link
Author

lukascivil commented May 11, 2022

This is not working for me, all other RTK features work except lazy query. Is there any specific configuration for this to work?

Code
image
image

Console Test
image

image

@SaulMoro
Copy link
Owner

It is not possible to combine the await method and the then-catch method.
Please use one of the two alternatives:

Method 1

startCounterById(id: string) {
    this.countQuery
      .fetch(id)
      .unwrap()
      .then((result) => {
        console.log('result method 1', result);
        this.form.reset();
      })
      .catch(console.error);
  }

Method 2

async startCounterById(id: string) {
    try {
      const result = await this.countQuery.fetch(id).unwrap();
      console.log('result method 2', result);
      this.form.reset();
    } catch (error) {
      console.error(error);
    }
  }

@lukascivil
Copy link
Author

lukascivil commented Sep 25, 2022

After a lot of testing, I think I found the problem. Running only fetch() and accessing the result as promised doesn't work, you have to use countQuery.state$ in the view.

To test just remove the use of countQuery.state$ from your example in lazy.component.ts and you will see that fetch() return undefined and break "unwrap()" prop access.

I don't understand why the problem exists. This is the expected behavior? did I get lost in something?

// lazy.component.ts
<div *ngIf="countQuery.state$ | async as countQuery" class="space-y-6">...</div>

// lazy.component.ts (THIS WILL BREAK IF WE DONT USE countQuery.state$)
this.countQuery
      .fetch(id, { preferCacheValue })
      .unwrap()   // BREAK :  Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'unwrap')
      .then((result) => {
        console.log('result method 1', result);
        this.form.reset();
      })
      .catch(console.error);

@lukascivil
Copy link
Author

lukascivil commented Sep 25, 2022

I did another test, performing the "subscription" programmatically, and it works.

It is possible to conclude that whenever we use "lazyQuery" we must subscribe the state. Is this statement correct? And if it's true, I think it's worth updating the docs.

// lazy.component.ts
countQuery = useLazyGetCountByIdQuery();
countQuerySubscription = this.countQuery.state$.subscribe();

@SaulMoro
Copy link
Owner

SaulMoro commented Mar 7, 2023

It is mandatory to connect to the state in a query/lazyQuery due to its nature, as we are supposed to access the data or state of the load. Nevertheless, we will study the implementation of making it independent so that it is not necessary.

@SaulMoro
Copy link
Owner

SaulMoro commented May 29, 2023

Fixed in 16.0.0-preview.0, the new signals based version.

@SaulMoro
Copy link
Owner

Fixed in 16.0.0-preview.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants