How to use “getEntityRecords” for user data?

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