How to use “getEntityRecords” for user data?

How can I use getEntityRecords for user data?

I have read these two posts, and it seems like that an endpoint for user is not included as the default entry for getEntityRecords in Gutenberg’s source code.

Is it possible to get user data through REST API to Gutenberg?

I have tried with this code, but it return an empty array

wp.data.select("core").getEntityRecords('user', 'user')

Gutenberg source code: https://github.com/WordPress/gutenberg/blob/e4b5330e61b61b64b7f3354b6a9d9a8c395a9aa9/packages/core-data/src/entities.js#L14

1 Answer
1

So I guess you’re still using WordPress version 5.3.x? 🙂

Because if so (and I was), then yes, the users endpoint (at wp/v2/users) is not included in the default entities.

But you can manually add it:

// Add the endpoint.
wp.data.dispatch( 'core' ).addEntities( [
    {
        name: 'user',
        kind: 'root',
        baseURL: '/wp/v2/users'
    }
] );

And that’s basically how it’s added/defined in WordPress 5.4.

Then to get the entity records, you’d do so, which should work in both WordPress 5.4 and 5.3.x:

// Get multiple records.
wp.data.select( 'core' ).getEntityRecords( 'root', 'user', { per_page: 3 } );

// Get a single record.
wp.data.select( 'core' ).getEntityRecord( 'root', 'user', 123 );

Alternate Options

Use wp.apiRequest()

Note that it uses jQuery.ajax(), so methods like done() and fail() can be used.

// Multiple records.
wp.apiRequest( { path: 'wp/v2/users', data: { per_page: 3 } } )
    .done( data => console.log( data ) )
    .fail( xhr => console.log( xhr.responseText ) );

// Single record.
wp.apiRequest( { path: 'wp/v2/users/123' } ).done( data => console.log( data ) );

Or use wp.apiFetch()

// Multiple records.
wp.apiFetch( { path: 'wp/v2/users', data: { per_page: 3 } } )
    .then( data => console.log( data ) )
    .catch( data => console.log( data.message ) ); // here, 'data' is an object

// Single record.
wp.apiFetch( { path: 'wp/v2/users/123' } ).then( data => console.log( data ) );

But whichever option you use, make sure you enqueue your script with the correct dependencies — for wp.apiRequest(), the script handle/ID is wp-api-request, whereas for wp.apiFetch(), it is wp-api-fetch.

Happy coding!


Update

In reply to your comment, yes, getEntityRecords() returns a null if the API request is not yet resolved (e.g. the browser is still receiving the response from the server).

So you can’t simply do result = wp.data.select( 'core' ).getEntityRecords( ... ) and expect the result to be always assigned with the response of the API request.

Instead, getEntityRecords() should be used with wp.data.select( 'core/data' ).isResolving() like so:

const { isResolving } = wp.data.select( 'core/data' );

// The last argument is the three arguments you passed to getEntityRecords().
isResolving( 'core', 'getEntityRecords', [ 'root', 'user', { per_page: 3 } ] );

Examples:

  1. Using wp.data.subscribe():

    const { subscribe, select } = wp.data;
    
    // Fetch users list.
    const query = { per_page: 3 };
    select( 'core' ).getEntityRecords( 'root', 'user', query );
    
    const unsubscribe = subscribe( () => {
        const { isResolving } = select( 'core/data' );
        const args = [ 'root', 'user', query ];
    
        if ( isResolving( 'core', 'getEntityRecords', args ) ) {
            console.log( 'still resolving' );
        } else {
            const data = select( 'core' ).getEntityRecords( 'root', 'user', query );
            console.log( 'data received', data );
    
            // We're done, so let's unsubscribe from the isResolving() check above.
            unsubscribe();
        }
    } );
    
  2. Using wp.data.withSelect():

    const { withSelect } = wp.data;
    const { createElement: el } = wp.element;
    
    const MyComponent = withSelect( select => {
        const { isResolving } = select( 'core/data' );
        const query = { per_page: 3 };
        return {
            users: select( 'core' ).getEntityRecords( 'root', 'user', query ),
            isRequesting: isResolving( 'core', 'getEntityRecords', [ 'root', 'user', query ] )
        };
    } )( props => {
        if ( props.isRequesting ) { // still resolving; so display a "loading" indicator
            return el( 'div', null, 'Loading data..' );
        }
    
        const list = props.users.map( user => el( 'li', { key: user.id }, user.name ) );
        return el( 'ul', null, list );
    } );
    
    // Then somewhere use el( MyComponent ) to render the custom element above.
    

And basically, if you’re creating a Gutenberg element, then you’d want to use getEntityRecords() with withSelect().

I hope that helps. 🙂

Leave a Comment