diff --git a/docs/designers-developers/developers/data/data-core.md b/docs/designers-developers/developers/data/data-core.md
index 8b1f9a41e3378..3d310092669ca 100644
--- a/docs/designers-developers/developers/data/data-core.md
+++ b/docs/designers-developers/developers/data/data-core.md
@@ -202,6 +202,21 @@ _Returns_
- `?Object`: The entity record's non transient edits.
+# **getEntityRecordNoResolver**
+
+Returns the Entity's record object by key. Doesn't trigger a resolver nor requests the entity from the API if the entity record isn't available in the local state.
+
+_Parameters_
+
+- _state_ `Object`: State tree
+- _kind_ `string`: Entity kind.
+- _name_ `string`: Entity name.
+- _key_ `number`: Record's key
+
+_Returns_
+
+- `?Object`: Record.
+
# **getEntityRecords**
Returns the Entity's records.
diff --git a/packages/core-data/README.md b/packages/core-data/README.md
index c1e1c27691fe8..ca399d641821d 100644
--- a/packages/core-data/README.md
+++ b/packages/core-data/README.md
@@ -415,6 +415,21 @@ _Returns_
- `?Object`: The entity record's non transient edits.
+# **getEntityRecordNoResolver**
+
+Returns the Entity's record object by key. Doesn't trigger a resolver nor requests the entity from the API if the entity record isn't available in the local state.
+
+_Parameters_
+
+- _state_ `Object`: State tree
+- _kind_ `string`: Entity kind.
+- _name_ `string`: Entity name.
+- _key_ `number`: Record's key
+
+_Returns_
+
+- `?Object`: Record.
+
# **getEntityRecords**
Returns the Entity's records.
diff --git a/packages/core-data/src/actions.js b/packages/core-data/src/actions.js
index 3a08117082084..681d4000998f6 100644
--- a/packages/core-data/src/actions.js
+++ b/packages/core-data/src/actions.js
@@ -357,11 +357,10 @@ export function* saveEntityRecord(
}
}
- // We perform an optimistic update here to clear all the edits that
- // will be persisted so that if the server filters them, the new
- // filtered values are always accepted.
+ // Get the full local version of the record before the update,
+ // to merge it with the edits and then propagate it to subscribers
persistedEntity = yield select(
- 'getEntityRecord',
+ 'getEntityRecordNoResolver',
kind,
name,
recordId
diff --git a/packages/core-data/src/selectors.js b/packages/core-data/src/selectors.js
index a4ea47ac8c745..495ebbbf94d79 100644
--- a/packages/core-data/src/selectors.js
+++ b/packages/core-data/src/selectors.js
@@ -107,6 +107,20 @@ export function getEntityRecord( state, kind, name, key ) {
return get( state.entities.data, [ kind, name, 'queriedData', 'items', key ] );
}
+/**
+ * Returns the Entity's record object by key. Doesn't trigger a resolver nor requests the entity from the API if the entity record isn't available in the local state.
+ *
+ * @param {Object} state State tree
+ * @param {string} kind Entity kind.
+ * @param {string} name Entity name.
+ * @param {number} key Record's key
+ *
+ * @return {Object?} Record.
+ */
+export function getEntityRecordNoResolver( state, kind, name, key ) {
+ return getEntityRecord( state, kind, name, key );
+}
+
/**
* Returns the entity's record object by key,
* with its attributes mapped to their raw values.
diff --git a/packages/core-data/src/test/actions.js b/packages/core-data/src/test/actions.js
index ffcee0efbca50..23e9463b03ebb 100644
--- a/packages/core-data/src/test/actions.js
+++ b/packages/core-data/src/test/actions.js
@@ -41,8 +41,11 @@ describe( 'saveEntityRecord', () => {
expect( fulfillment.next( entities ).value.type ).toBe(
'SAVE_ENTITY_RECORD_START'
);
+
+ // Should select getEntityRecordNoResolver selector (as opposed to getEntityRecord)
+ // see https://github.com/WordPress/gutenberg/pull/19752#discussion_r368498318.
expect( fulfillment.next().value.type ).toBe( 'SELECT' );
- expect( fulfillment.next().value.type ).toBe( 'SELECT' );
+ expect( fulfillment.next().value.selectorName ).toBe( 'getEntityRecordNoResolver' );
expect( fulfillment.next().value.type ).toBe( 'SELECT' );
expect( fulfillment.next().value.type ).toBe( 'RECEIVE_ITEMS' );
const { value: apiFetchAction } = fulfillment.next( {} );
diff --git a/packages/core-data/src/test/selectors.js b/packages/core-data/src/test/selectors.js
index ae75557d40f1a..07a2540d6dd4e 100644
--- a/packages/core-data/src/test/selectors.js
+++ b/packages/core-data/src/test/selectors.js
@@ -8,6 +8,7 @@ import deepFreeze from 'deep-freeze';
*/
import {
getEntityRecord,
+ getEntityRecordNoResolver,
getEntityRecords,
getEntityRecordChangesByRecord,
getEntityRecordNonTransientEdits,
@@ -20,7 +21,11 @@ import {
getReferenceByDistinctEdits,
} from '../selectors';
-describe( 'getEntityRecord', () => {
+// getEntityRecord and getEntityRecordNoResolver selectors share the same tests
+describe.each( [
+ [ getEntityRecord ],
+ [ getEntityRecordNoResolver ],
+] )( '%p', ( selector ) => {
it( 'should return undefined for unknown record’s key', () => {
const state = deepFreeze( {
entities: {
@@ -36,7 +41,7 @@ describe( 'getEntityRecord', () => {
},
},
} );
- expect( getEntityRecord( state, 'root', 'postType', 'post' ) ).toBe( undefined );
+ expect( selector( state, 'root', 'postType', 'post' ) ).toBe( undefined );
} );
it( 'should return a record by key', () => {
@@ -56,7 +61,9 @@ describe( 'getEntityRecord', () => {
},
},
} );
- expect( getEntityRecord( state, 'root', 'postType', 'post' ) ).toEqual( { slug: 'post' } );
+ expect( selector( state, 'root', 'postType', 'post' ) ).toEqual( {
+ slug: 'post',
+ } );
} );
} );