4

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

0

1 Answer 1

15

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. :)

13
  • This is really helpful! I have updated to 5.4 and tried that code, but it only returns null. I have tried it multiple times to ensure it is not the null that I may get for the first call. What did I missed? The code I tried to use: const result = wp.data.select("core").getEntityRecords('root', 'user', { per_page: 3 }); console.log(result);
    – Winston
    Apr 7, 2020 at 13:00
  • Wait no this is working, but it only works when I type it into the console. Why was that???
    – Winston
    Apr 7, 2020 at 13:04
  • 1
    Dear Sally CJ, thank you very march for your answer!!! I'm study gutenberg, but never hear about this methods. Now one of the my big problem - is working with data. Please, say me - how you know about working with data ? Apr 8, 2020 at 7:37
  • 2
    @GayratVlasov, I basically referred to the handbook, the official examples and the source code like the Latest Posts block. There are also various tutorials you can find via Google.. :) Good luck!
    – Sally CJ
    Apr 9, 2020 at 8:05
  • 1
    As an update, you can now also use const { records, hasResolved } = useEntityRecords( "root", "user", { per_page: 5 } ); where the final object supports any params in the user rest endpoint. Feb 27 at 21:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.