Framework: Fetch categories by common terms resolver#5826
Framework: Fetch categories by common terms resolver#5826
Conversation
| */ | ||
| export async function* getTerms( taxonomy ) { | ||
| yield setRequested( 'terms', taxonomy ); | ||
| const restBase = getTaxonomyRESTBase( taxonomy ); |
There was a problem hiding this comment.
I wonder if we could avoid the apiRequest.settings by fetching the rest base from /wp/v2/taxonomies or something? A resolver calling another resolver? Any thoughts on this.
Just trying to avoid as much globals as we can
There was a problem hiding this comment.
Thinking more about this, getTaxonomy could be a selector with a side effect.
const { rest_base: restBase } = yield select( 'core' ).getTaxonomy( taxonomy ) which will call the side effect only once.
There was a problem hiding this comment.
I guess we need a resolve here because we want to wait for fulfillment
There was a problem hiding this comment.
That might work. We'd definitely want to bootstrap this data, to avoid the additional request occurring in the client before being able to resolve terms. Bootstrapping support might be something we want anyways.
Part of the goal in assigning wpApiSettings into apiRequest was to avoid the introduction of another global, since apiRequest is already faked into module form as @wordpress/api-request.
There was a problem hiding this comment.
wp.apiRequest.settings is definitely better than wpApiSettings or wp.api.*, we'd have a unique root global dependency wp.apiRequest. If you think we can try the resolver approach separately, I'm fine with that.
|
Another issue with separate resolvers is that because the data module memoizes per function, calling To your previous point, maybe this is where we ought to go through the |
|
One other option, which could also help address another issue I'm encountering†, is to introduce the Previously we considered it being an object. I'm wondering also if it could just be a property of the resolver function. export async function* getTerms( state, taxonomy ) {
yield setRequested( 'terms', taxonomy );
const restBase = getTaxonomyRESTBase( taxonomy );
const terms = await apiRequest( { path: '/wp/v2/' + restBase } );
yield receiveTerms( taxonomy, terms );
}
getTerms.isFulfilled = ( state, taxonomy ) => {
// return hasRequestedTerms( state, taxonomy );
return state.terms[ taxonomy ] !== undefined;
};† I'm trying to refactor the Even if this was implemented another way (e.g. separate selector like |
|
Or, if the resolver has access to state, it can simply abort itself if no action is necessary. |
|
I'd love if we avoid the Maybe it could be optional, if provided use it, if not use memoization |
Since we synchronously yield This is the idea anyways. I'm having trouble with this in practice, where each call to |
|
It appears to be that since the asynchronous iterator of Related: |
|
@aduth Funny, that's exactly why I created |
Is it a simple change? Or are we talking introduction of wrapping functions and custom vocabulary? |
|
Since we're not supporting a lot of yieldable values, I believe it should be simple. I haven't looked in detail to the way you implemented the engine behind the generators syntax but I don't think it's a complex task, just replace the promise usage, using simple callbacks (success, error) |
|
Here's the whole rungen engine implementation https://github.com/youknowriad/rungen/blob/master/src/create.js#L4-L36 We could use exactly the same implementation and just replace the controls array here https://github.com/youknowriad/rungen/blob/master/src/create.js#L5 with an array containing only our action control. A control is basically the behavior saying We only support one unique control in wp.data the action control. |
|
@aduth @youknowriad Is this PR still relevant? |
|
Yes, this still has value, but needs to be brought up to date. Specifically, we can leverage the At least this can serve as an adequate solution for our needs here. The complexities of handling asynchronous dispatching may still warrant more investigation separately. |
|
I believe this is no longer required with the more recent entities implementation (#6939). |
This pull request is part of a series of pull request targeted at more complex use of selector resolvers introduced in #5219, namely toward paginated hierarchical terms picker.
This pull request seeks to refactor the category resolver implemented in #5219 to generalize its use toward terms fetching. There are no changes to the public interface for consuming categories, and it's expected that a
getCategoriesselector will remain long-term as a boon to developer usability. The changes here enhance the existinggetTermsselector on which categories extends to support resolution of other terms. This includes necessary changes to allow access to the REST base mappings within the core data module (viawp.apiRequest.settings).Implementation notes:
It would be nice if we wouldn't need a standalone
getCategoriesresolver, considering that thegetCategoriesselector calls thegetTermsselector, there should only need to be a resolver forgetTerms. However, because selecting within a module's own selectors does not flow through the data module's abstraction, it does not trigger these resolvers automatically. While disappointing, this is a relatively minor consideration.Testing instructions:
Verify there are no regressions in the display of categories block.
Verify there are no regressions in the behavior of
withAPIData, whose provider has been slightly revised here. Example: Category picker.