WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.46k stars 4.18k forks source link

getEntityRecords returns nothing if one of the included IDs doesn't exist #28429

Closed philbuchanan closed 3 years ago

philbuchanan commented 3 years ago

Description

When using the include parameter with getEntityRecords, if one of the specific posts to include doesn't exist, it never returns anything.

Step-by-step reproduction instructions

See code below.

Expected behaviour

I would expect an array with objects for the IDs that do exist.

Actual behaviour

As far as I can tell, nothing is ever returned.

Code snippet (optional)

I am using this in the edit function of a custom block:

const ids = [ /* media IDs */ ];
const images = useSelect( ( select ) => {
    return select( 'core' ).getEntityRecords( 'postType', 'attachment', {
        include: ids,
    } );
} );

If the ids array contains only media item IDs that exist, it returns an array of media objects as expected. However, if the ids array contains an ID of a media item that doesn't exist (for example, you permanently delete that media item), it never returns anything—the images variable never gets updated.

If I use apiFetch instead, it does return an array of media objects, with the invalid one removed:

apiFetch( {
    path: addQueryArgs( '/wp/v2/media', {
        include: ids.join( ',' ),
    } ),
} )

I would expect getEntityRecords to behave similar to apiFetch in this regard.

WordPress information

Device information

talldan commented 3 years ago

Thanks for reporting this. From what I can see, the REST API returns the items that exist, but then getEntityRecords at some point filters them out. Seems like an unexpected result, so I'd consider it a bug.

Mamaduka commented 3 years ago

I think this line is the culprit for this issue:

https://github.com/WordPress/gutenberg/blob/29cd8eda717ec20a33ab4b95855652be758dd58d/packages/core-data/src/queried-data/selectors.js#L70-L72

This check will abort the loop and return null when we have itemId (from includes) but not the actual item in the state.

The fix seems easy, but I want to do more tests before creating PR to avoid regressions.

Mamaduka commented 3 years ago

The PR is ready for review #34034.

studionenontwerp commented 2 years ago

Also wp.data.select( 'core' ).getMediaItems( {include: ids } ) returns NULL if one of the ids does not exist any more.

Mamaduka commented 2 years ago

Hi, @studionenontwerp

This issue should be fixed in the latest Gutenberg plugin and will ship with WP 5.9.

P.S. wp.data.select( 'core' ).getMediaItems( {include: ids } ) might return null on first invocation, if data isn't in state. Calling it second time will return results. This is automatically handled by useSelect hook.