Skip to content

Conversation

@DyBev
Copy link

@DyBev DyBev commented Jul 4, 2025

Description

There is a small edge case where when a call is waiting for another call to finish - think A2 needs data from A1.
on the first render
A2 options.defer = true; isLoading == false as a result;
A1 options.defer = false && data = undefined; isLoading == true as a result;

After A1 data has been fetched, A2 options.defer = false.
However because it isn't the first render isLoading == false, and the loading state is only set to true during the runAsync function call.

To remedy this I've added an extra check that is the same as the check in the useEffect which will be checking (!options.defer && !data && !isLoading && !error) if all of these statements are true then we can assume that the runAsync function will be triggered in the useEffect.

Motivation and Context

potentially solves issue #81
Also potentially solves an issue found by a team in American express.

How Has This Been Tested?

Manual testing was completed following the reproduction steps as outlined on issue #81, as well as manual testing on the branch where the issue was found.

Currently available fetchye package. repository
Screenshot 2025-07-04 at 11 39 09

Fetchye package using a build produced from this branch. repository
Screenshot 2025-07-04 at 11 40 06

Types of Changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation (adding or updating documentation)
  • Dependency update

Checklist:

  • My change requires a change to the documentation and I have updated the documentation accordingly.
  • My changes are in sync with the code style of this project.
  • There aren't any other open Pull Requests for the same issue/update.
  • These changes should be applied to a maintenance branch.
  • I have added the Apache 2.0 license header to any new files created.

What is the Impact to Developers Using Fetchye?

@DyBev
Copy link
Author

DyBev commented Jul 4, 2025

With this change could the first render logic be removed from the isLoading function?

@DyBev DyBev marked this pull request as ready for review July 4, 2025 10:20
@DyBev DyBev requested review from a team as code owners July 4, 2025 10:20
@DyBev DyBev force-pushed the fix/isLoading/multi-render-behaviour-weirdness branch from 2b7e0ba to fd44eb6 Compare July 9, 2025 10:05
@DyBev
Copy link
Author

DyBev commented Jul 9, 2025

Added the code changes in #98 to a branch here and ran the package locally.

the changes don't interfer with my changes. Will need to re-create the implementation of #98 to test if my changes interfer with that
Screenshot 2025-07-09 at 11 10 47

@DyBev
Copy link
Author

DyBev commented Jul 23, 2025

Converting to draft whilst pr #102 is open

@DyBev DyBev marked this pull request as draft July 23, 2025 08:17
@DyBev
Copy link
Author

DyBev commented Aug 20, 2025

Testing for sequential calls

Fetchye v1.7.1
Screenshot 2025-08-20 at 10 55 22

Fetchye with these changes
Screenshot 2025-08-20 at 11 00 21

@DyBev
Copy link
Author

DyBev commented Aug 20, 2025

Testing for id changing after render

note: there is potentially an issue where the initial return will return the data from the previous id. see #105

Fetchye with these changes
Screenshot 2025-08-20 at 13 25 11

@DyBev
Copy link
Author

DyBev commented Aug 20, 2025

testing again forceFetch functionality

Fetchye 1.7.1
Screenshot 2025-08-20 at 13 37 34

Fetchye with these changes
Screenshot 2025-08-20 at 13 25 28

@DyBev DyBev marked this pull request as ready for review September 11, 2025 07:45
Copy link
Member

@code-forger code-forger left a comment

Choose a reason for hiding this comment

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

Thanks for the contribution, I think there is one logic regression. if you could make some unit tests to prove this is a regression, then fix it, that would be great.

I've also asked for a slight reinforcing of the unit tests, possibly even in some that you did not author. Since you are changing rather complex logic, laying down more tests will help the package consumers be confident that this change has no logic regressions.

// if defer is true
if (options.defer) {
// isLoading should be false
return false;
Copy link
Member

Choose a reason for hiding this comment

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

If the caller passes in three quick renders:

  1. defer: true
  2. defer: false
  3. defer: true

then isLoading will now go false despite the fact there may still be a call in flight.

This check might need to be

if (options.defer && numOfRenders === 1) {

Copy link
Author

Choose a reason for hiding this comment

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

updated the code c75cceb

I've moved the defer to only stop the function from returning true if fetchye will fetch, rather than an early false return if defer is enabled.

expect(isLoading({
loading: false, data: undefined, numOfRenders: 1, options: { forceInitialFetch: true },
loading: false,
numOfRenders: 1,
Copy link
Member

Choose a reason for hiding this comment

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

your function no-longer receives this parameter, please remove it from the test

Copy link
Author

Choose a reason for hiding this comment

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

Removed in this commit e45edff

it('should return false defer is true', () => {
expect(isLoading({
loading: false, data: undefined, options: { defer: true }, error: undefined, refs: {},
})).toEqual(false);
Copy link
Member

Choose a reason for hiding this comment

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

I would like to see some more expects per test:

This tests proves that for the above set of inputs, you get false, but does not prove that should return false if defer is true, since you have not checked other combinations of inputs.

So in this same it block, having many combinations of isLoading, data, options, error, and refs, showing that for any combination, when defer: true => false

Copy link
Member

Choose a reason for hiding this comment

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

(same for other tests in this file)

Copy link
Author

@DyBev DyBev Sep 24, 2025

Choose a reason for hiding this comment

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

I've refactored the tests a little to make use of more describe blocks: cb0ffc1

I've added a should return false and should return true describe blocks with each case in it() this way any failures will highlight the case where it failed, I put them all into 2 "true" or "false" with multiple expects, but when it failed it was tricky to figure out which one was the failing case

} from '../src/queryHelpers';

describe('isLoading', () => {
it('should return false defer is true', () => {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
it('should return false defer is true', () => {
it('should return false if defer is true', () => {

Copy link
Author

Choose a reason for hiding this comment

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

added in this commit e45edff

@DyBev DyBev requested a review from code-forger September 24, 2025 15:49
@Matthew-Mallimo Matthew-Mallimo enabled auto-merge (squash) November 13, 2025 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants