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

Data Module: Add isFulfilled API for advanced resolver use cases #6084

Merged
merged 3 commits into from Apr 12, 2018

Conversation

Projects
None yet
3 participants
@youknowriad
Contributor

youknowriad commented Apr 9, 2018

In some advanced use cases, the memoization of the resolvers is not enough to avoid similar requests to be triggered multiple times:

  • When using complex args (new instance of objects)
  • Multiple generators dealing with the same data.

To solve this, I'm introducing an isFulfilled API to the resolvers.

We can now write resolvers like this:

const myResolver: { 
  fulfill: ( state, ...args ) => // do something.
  isFulfilled: ( state, ...args ) => // returns a boolean. 
},

This resolver will be triggered each time we call the selector unless isFulfilled returns true.

Testing instructions

Nothing is changing for now, I'm planning to use this in #5875

@aduth

Curious whether you have any thoughts on just making this a property of the resolver function. Seems like it's a bit more intuitive to migrate a function to having more advanced isFulfilled behavior, as it's just adding a property instead of reshaping as an object:

function myResolver( state, ...args ) {
	// do something.
}

myResolver.isFulfilled = ( state, ...args ) => {
	// returns a boolean.
};
const rawFullfill = async ( ...args ) => {

This comment has been minimized.

@aduth

aduth Apr 11, 2018

Member

Typo: "Fullfill" -> "Fulfill"

const fulfill = memoize( async ( ...args ) => {
const store = stores[ reducerKey ];
const store = stores[ reducerKey ];
const resolver = isPlainObject( newResolvers[ key ] ) ? newResolvers[ key ] : { fulfill: newResolvers[ key ] };

This comment has been minimized.

@aduth

aduth Apr 11, 2018

Member

Personal preference: Since we're only re-shaping this if not already a plain object, seems we'd only need a condition for that, not if/else, avoiding repetition of property access:

let resolver = newResolvers[ key ];
if ( ! isPlainObject( resolver ) ) {
	resolver = { fulfill: resolver };
}
@youknowriad

This comment has been minimized.

Contributor

youknowriad commented Apr 11, 2018

Curious whether you have any thoughts on just making this a property of the resolver function.

That was an option I considered and honestly I don't feel strongly either way. I opted for the object approach in anticipation for future potential properties (caching invalidation etc...), I feel the object scales better instead of assigning several keys.

@atimmer

atimmer approved these changes Apr 11, 2018 edited

Looks good.

I think I agree with @youknowriad that the object approach is the way to go. It looks more straightforward.

@aduth

This comment has been minimized.

Member

aduth commented Apr 11, 2018

I wonder if we really need to be opinionated on it, or if we just check for the property whether it's an object or other:

let resolver = newResolvers[ key ];
if ( ! resolver ) {
	return selector;
}

if ( ! resolver.fulfill ) {
	resolver = { fulfill: resolver };
}

I'm fine with as-is too.

@youknowriad

This comment has been minimized.

Contributor

youknowriad commented Apr 12, 2018

Update the PR to be less opinionated about it :)

@youknowriad youknowriad merged commit 14bb454 into master Apr 12, 2018

2 checks passed

codecov/project 44.44% (+0.03%) compared to 503ddba
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details

@youknowriad youknowriad deleted the try/data-module-is-fulfilled branch Apr 12, 2018

@youknowriad youknowriad added this to the 2.7 milestone Apr 12, 2018

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