WordPress / gutenberg

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

Regression: Error when using nested properties in `_fields` with `getEntityRecord()` #54735

Closed kraftner closed 1 year ago

kraftner commented 1 year ago

Description

When requesting something from the REST API using wp.data.select('core').getEntityRecord() this can result in an uncaught Type Error.

I noticed this when trying to get back the routes field removed in https://github.com/WordPress/gutenberg/pull/39256/files#diff-38a74d088ea018dbbea00d8f5bd5c03ea54bfc099d1d1836686c24a5582bf579R27-R39 using the _fields parameter.

Here is an example. Just run this code in the console when editing a post:

wp.data.select('core').getEntityRecord()'root', '__unstableBase', undefined, { _fields: [ 'routes./wp/v2/posts' ] })

Yes, I know, I am using __unstableBase here which is a private API. But please still hear me out since the surfaced issue is a fundamental bug that probably can also occur in other situations. I just wasn't able to find another example quickly now.


I think this issue appeared when removing Lodash _.get() in https://github.com/WordPress/gutenberg/commit/4b12c75df261f62c7ca5312c900628920338b16b#diff-6fae435c7327c5edb1a67718054b7ee8513d4691a19b416e7d5f628aefc4459bR69-R72 of #48310.

The problem is that using the dot syntax to limit the retrieved data to a nested property tries to get a property of undefined here when first requesting the data:

https://github.com/WordPress/gutenberg/blob/a5a32c1da19589a60d48ae793a3d0a5a48223db6/packages/core-data/src/queried-data/selectors.js#L71

which fails with the Type Error mentioned above.

This is also confirmed by the fact that the following runs flawlessly:

wp.data.select('core').getEntityRecord('root', '__unstableBase', undefined, { _fields: [ 'routes' ] })

The old implementation with Lodash _.get()

https://github.com/WordPress/gutenberg/blob/e086b2b595618a5f4c9491119695be3e074d736b/packages/core-data/src/queried-data/selectors.js#L69

though would handle this edge case returning undefined instead of causing a Type Error in both cases.


So as a solution I'd assume an additional check for undefined would solve this issue. Something along the lines of

value = typeof value === 'undefined' ? undefined: value[fieldName];

Which a quick check altering WP 6.3 core confirmed.

Step-by-step reproduction instructions

  1. Open the block editor

  2. Run wp.data.select('core').getEntityRecord()'root', '__unstableBase', undefined, { _fields: [ 'routes./wp/v2/posts' ] }) in the console

  3. See a "Uncaught TypeError: value is undefined".

  4. Open the block editor (reload, doesn't work when the data has been requested before)

  5. Run wp.data.select('core').getEntityRecord()'root', '__unstableBase', undefined, { _fields: [ 'routes' ] }) in the console

  6. See no error but a value of undefined returned.

Screenshots, screen recording, code snippet

No response

Environment info

Please confirm that you have searched existing issues in the repo.

Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

Yes

Mamaduka commented 1 year ago

@tyxla, do you have time to look into this?

tyxla commented 1 year ago

Thanks for the thorough report @kraftner and for the ping @Mamaduka.

I'm happy to take a look this week.

tyxla commented 1 year ago

Fix is in #54790.