Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core-data] throwOnError option for saveEntityRecord and deleteEntityRecord actions #39258

Merged
merged 14 commits into from
Mar 16, 2022

Conversation

adamziel
Copy link
Contributor

@adamziel adamziel commented Mar 7, 2022

Description

This is a continuation of Entity records hooks.

An original idea was to make creating, editing, and deleting entity records easier by introducing a specialized convenience wrapper such as useEntityMutation:

const {
	edit,
	editedRecord,
	hasEdits,
	saveEdits,
	isSaving,
	saveError
} = useEntityMutation( 'postType', 'page', pageId );

The rationale – that the full flow is not easy to figure out, confusing at times, and it is easy to omit a part or two. For example, to edit a record, save it, and display a progress indicator and any error information, you need at least the following information and actions:

const {
	editEntityRecord,
	saveEditedEntityRecord
} = useDispatch( coreStore );

const { editedRecord, hasEdits, isSaving, saveError } = useSelect(
	( select ) => {
		const args = [kind, type, id];
		return {
			editedRecord: select( coreStore ).getEditedEntityRecord( ...args ),
			hasEdits: select( coreStore ).hasEditsForEntityRecord( ...args ),
			isSaving: select( coreStore ).isSavingEntityRecord( ...args ),
			saveError: select( coreStore ).getLastEntitySaveError( ...args ),
		};
	},
	[kind, type, id],
);

Diving deeper, we realized that it is hard to distinguish between creating and updating records when both use-cases are crammed within a single useEntityMutation hook.

In this PR, I explored three smaller hooks called useEntityRecordCreate, useEntityRecordUpdate, and useEntityRecordDelete. See the relevant commit.

However, it quickly occurred to me that we only rely on all these selectors because we do not embrace the full power of promises. For example, the Gutenberg codebase commonly relies on the following pattern:

	const templatePart = await saveEntityRecord(
		'postType',
		'wp_template_part',
		{
			slug: cleanSlug,
			title,
			content: '',
			area,
		}
	);

	const lastEntitySaveError = getLastEntitySaveError(
		'postType',
		'wp_template_part',
		templatePart.id
	);
	if ( lastEntitySaveError ) {
		throw lastEntitySaveError;
	}

This looks a whole lot like what we do in PHP:

$result = create_post();
if ( is_wp_error( $result ) ) {
    return $result;
}

What if we used promises instead? Even better, what if we ditched the hooks and used the promises right in the store so that other stores could benefit from that as well? And so this is the proposal this PR makes:

try {
	const templatePart = await saveEntityRecord(
		'postType',
		'wp_template_part',
		{
			slug: cleanSlug,
			title,
			content: '',
			area,
		},
		{ throwOnError: true }
	);
} catch ( e ) {
	// Display an error notice
}

It takes care of:

  • The errors, since they're thrown.
  • The loading state, since we know whether the promise is still running or not. Of course, isSavingEntityRecord may still be used when needed or more convenient.

Different angles

Re-throwing errors is different than having a convenience wrapper for actions like editEntityRecord, saveEditedEntityRecord, saveEntityRecord and the getEditedEntityRecord selector. Perhaps that's where a hook would actually shine:

const { create, isCreating, error } = useEntityRecordCreate();
const { editedRecord, applyEdits, saveEdits, isSaving, error } = useEntityRecordEdit();
const { remove, isRemoving, error } = useEntityRecordRemove(); // it's "remove", because "delete" is a reserved keyword

However, given the "throwing" actions, accessing error and isCreating/isSaving/isRemoving would not be needed as often, which leaves us with just:

const { create } = useEntityRecordCreate();
const { editedRecord, applyEdits, saveEdits } = useEntityRecordEdit();
const { remove } = useEntityRecordRemove();

Which doesn't do much for creating and removing records, so we could also ditch these hooks and settle only for the useEntityRecordEdit hook:

const { editedRecord, applyEdits, saveEdits } = useEntityRecordEdit();

I'm interested in your thoughts about all that.

cc @gziolo @kevin940726 @getdave @noisysocks @scruffian @draganescu

@adamziel adamziel requested a review from nerrad as a code owner March 7, 2022 15:44
@adamziel adamziel changed the title Propose hooks for creating, deleting, and updating entity records Hooks for creating, deleting, and updating entity records Mar 7, 2022
@github-actions
Copy link

github-actions bot commented Mar 7, 2022

Size Change: +2 B (0%)

Total Size: 1.16 MB

Filename Size Change
build/core-data/index.min.js 14.2 kB +66 B (0%)
build/edit-navigation/index.min.js 16.1 kB -10 B (0%)
build/edit-post/index.min.js 29.8 kB +16 B (0%)
build/edit-site/index.min.js 43.8 kB -53 B (0%)
build/edit-widgets/index.min.js 16.5 kB -17 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 993 B
build/admin-manifest/index.min.js 1.24 kB
build/annotations/index.min.js 2.77 kB
build/api-fetch/index.min.js 2.27 kB
build/autop/index.min.js 2.15 kB
build/blob/index.min.js 487 B
build/block-directory/index.min.js 6.49 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
build/block-editor/index.min.js 145 kB
build/block-editor/style-rtl.css 15 kB
build/block-editor/style.css 15 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 445 B
build/block-library/blocks/button/editor.css 445 B
build/block-library/blocks/button/style-rtl.css 560 B
build/block-library/blocks/button/style.css 560 B
build/block-library/blocks/buttons/editor-rtl.css 292 B
build/block-library/blocks/buttons/editor.css 292 B
build/block-library/blocks/buttons/style-rtl.css 275 B
build/block-library/blocks/buttons/style.css 275 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 103 B
build/block-library/blocks/code/style.css 103 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 406 B
build/block-library/blocks/columns/style.css 406 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-template/style-rtl.css 127 B
build/block-library/blocks/comment-template/style.css 127 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-query-loop/editor-rtl.css 95 B
build/block-library/blocks/comments-query-loop/editor.css 95 B
build/block-library/blocks/cover/editor-rtl.css 546 B
build/block-library/blocks/cover/editor.css 547 B
build/block-library/blocks/cover/style-rtl.css 1.56 kB
build/block-library/blocks/cover/style.css 1.56 kB
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 417 B
build/block-library/blocks/embed/style.css 417 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 255 B
build/block-library/blocks/file/style.css 255 B
build/block-library/blocks/file/view.min.js 353 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 965 B
build/block-library/blocks/gallery/editor.css 967 B
build/block-library/blocks/gallery/style-rtl.css 1.61 kB
build/block-library/blocks/gallery/style.css 1.61 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 159 B
build/block-library/blocks/group/editor.css 159 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 114 B
build/block-library/blocks/heading/style.css 114 B
build/block-library/blocks/html/editor-rtl.css 332 B
build/block-library/blocks/html/editor.css 333 B
build/block-library/blocks/image/editor-rtl.css 731 B
build/block-library/blocks/image/editor.css 730 B
build/block-library/blocks/image/style-rtl.css 529 B
build/block-library/blocks/image/style.css 535 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 199 B
build/block-library/blocks/latest-posts/editor.css 198 B
build/block-library/blocks/latest-posts/style-rtl.css 447 B
build/block-library/blocks/latest-posts/style.css 446 B
build/block-library/blocks/list/style-rtl.css 94 B
build/block-library/blocks/list/style.css 94 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 493 B
build/block-library/blocks/media-text/style.css 490 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 708 B
build/block-library/blocks/navigation-link/editor.css 706 B
build/block-library/blocks/navigation-link/style-rtl.css 94 B
build/block-library/blocks/navigation-link/style.css 94 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation-submenu/view.min.js 375 B
build/block-library/blocks/navigation/editor-rtl.css 2.03 kB
build/block-library/blocks/navigation/editor.css 2.04 kB
build/block-library/blocks/navigation/style-rtl.css 1.89 kB
build/block-library/blocks/navigation/style.css 1.88 kB
build/block-library/blocks/navigation/view.min.js 2.85 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 363 B
build/block-library/blocks/page-list/editor.css 363 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 273 B
build/block-library/blocks/paragraph/style.css 273 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/style-rtl.css 446 B
build/block-library/blocks/post-comments-form/style.css 446 B
build/block-library/blocks/post-comments/style-rtl.css 521 B
build/block-library/blocks/post-comments/style.css 521 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 721 B
build/block-library/blocks/post-featured-image/editor.css 721 B
build/block-library/blocks/post-featured-image/style-rtl.css 153 B
build/block-library/blocks/post-featured-image/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 323 B
build/block-library/blocks/post-template/style.css 323 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 80 B
build/block-library/blocks/post-title/style.css 80 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 389 B
build/block-library/blocks/pullquote/style.css 388 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 234 B
build/block-library/blocks/query-pagination/style.css 231 B
build/block-library/blocks/query/editor-rtl.css 131 B
build/block-library/blocks/query/editor.css 132 B
build/block-library/blocks/quote/style-rtl.css 201 B
build/block-library/blocks/quote/style.css 201 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 397 B
build/block-library/blocks/search/style.css 398 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 B
build/block-library/blocks/separator/editor-rtl.css 99 B
build/block-library/blocks/separator/editor.css 99 B
build/block-library/blocks/separator/style-rtl.css 233 B
build/block-library/blocks/separator/style.css 233 B
build/block-library/blocks/separator/theme-rtl.css 172 B
build/block-library/blocks/separator/theme.css 172 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 744 B
build/block-library/blocks/site-logo/editor.css 744 B
build/block-library/blocks/site-logo/style-rtl.css 181 B
build/block-library/blocks/site-logo/style.css 181 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 177 B
build/block-library/blocks/social-link/editor.css 177 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.37 kB
build/block-library/blocks/social-links/style.css 1.36 kB
build/block-library/blocks/spacer/editor-rtl.css 332 B
build/block-library/blocks/spacer/editor.css 332 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 471 B
build/block-library/blocks/table/editor.css 472 B
build/block-library/blocks/table/style-rtl.css 481 B
build/block-library/blocks/table/style.css 481 B
build/block-library/blocks/table/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 226 B
build/block-library/blocks/tag-cloud/style.css 227 B
build/block-library/blocks/template-part/editor-rtl.css 235 B
build/block-library/blocks/template-part/editor.css 235 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 571 B
build/block-library/blocks/video/editor.css 572 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/common-rtl.css 934 B
build/block-library/common.css 932 B
build/block-library/editor-rtl.css 9.96 kB
build/block-library/editor.css 9.96 kB
build/block-library/index.min.js 168 kB
build/block-library/reset-rtl.css 474 B
build/block-library/reset.css 474 B
build/block-library/style-rtl.css 11.4 kB
build/block-library/style.css 11.4 kB
build/block-library/theme-rtl.css 665 B
build/block-library/theme.css 670 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/blocks/index.min.js 46.5 kB
build/components/index.min.js 218 kB
build/components/style-rtl.css 15.6 kB
build/components/style.css 15.6 kB
build/compose/index.min.js 11.2 kB
build/customize-widgets/index.min.js 11.2 kB
build/customize-widgets/style-rtl.css 1.39 kB
build/customize-widgets/style.css 1.39 kB
build/data-controls/index.min.js 663 B
build/data/index.min.js 8.19 kB
build/date/index.min.js 31.9 kB
build/deprecated/index.min.js 518 B
build/dom-ready/index.min.js 336 B
build/dom/index.min.js 4.53 kB
build/edit-navigation/style-rtl.css 4.04 kB
build/edit-navigation/style.css 4.05 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/style-rtl.css 7.07 kB
build/edit-post/style.css 7.07 kB
build/edit-site/style-rtl.css 7.44 kB
build/edit-site/style.css 7.42 kB
build/edit-widgets/style-rtl.css 4.39 kB
build/edit-widgets/style.css 4.39 kB
build/editor/index.min.js 38.4 kB
build/editor/style-rtl.css 3.71 kB
build/editor/style.css 3.71 kB
build/element/index.min.js 4.29 kB
build/escape-html/index.min.js 548 B
build/format-library/index.min.js 6.62 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.66 kB
build/html-entities/index.min.js 454 B
build/i18n/index.min.js 3.79 kB
build/is-shallow-equal/index.min.js 535 B
build/keyboard-shortcuts/index.min.js 1.83 kB
build/keycodes/index.min.js 1.41 kB
build/list-reusable-blocks/index.min.js 1.75 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 2.94 kB
build/notices/index.min.js 957 B
build/nux/index.min.js 2.12 kB
build/nux/style-rtl.css 751 B
build/nux/style.css 749 B
build/plugins/index.min.js 1.98 kB
build/preferences/index.min.js 1.2 kB
build/primitives/index.min.js 949 B
build/priority-queue/index.min.js 611 B
build/react-i18n/index.min.js 704 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/redux-routine/index.min.js 2.69 kB
build/reusable-blocks/index.min.js 2.24 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 11.1 kB
build/server-side-render/index.min.js 1.61 kB
build/shortcode/index.min.js 1.52 kB
build/token-list/index.min.js 668 B
build/url/index.min.js 1.99 kB
build/viewport/index.min.js 1.08 kB
build/warning/index.min.js 280 B
build/widgets/index.min.js 7.21 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.07 kB

compressed-size-action

@adamziel adamziel added [Package] Core data /packages/core-data [Type] Code Quality Issues or PRs that relate to code quality labels Mar 9, 2022
@adamziel adamziel self-assigned this Mar 9, 2022
@adamziel adamziel changed the title Hooks for creating, deleting, and updating entity records Throwing actions for creating, deleting, and updating entity records Mar 9, 2022
@draganescu
Copy link
Contributor

Looking at the resulting code, somehow the more verbose code seems more readable? It's like a story.

@noisysocks
Copy link
Member

You didn't used to be able to await an action like you can now which is why the API is a bit clunky 🙂

I like the idea, but I don't find the API to be very intuitive if I'm honest. That is, when I read the code, I don't instantly know what it will do. What do you think about a param?

await saveEditedEntityRecord(
 	'postType',
 	template.type,
 	template.id,
	{ throwOnError: true }
);

@gziolo
Copy link
Member

gziolo commented Mar 11, 2022

I'm not familiar with the existing codebase that uses the flow that is discussed in this PR, but I must admit that the proposal from @noisysocks in #39258 (comment) sounds reasonable. This way we can reduce the boilerplate code and we still leave the choice to the developer how it should be handled. The challenge for public APIs is that you rather want to minimize the number of methods exposed to optimize for the most common usage and easier discovery. This goes in contrast to the consuming projects where a new method might help to make the code more readable.

This is a continuation of Entity records hooks.
An original idea was to make creating, editing, and deleting entity records easier by introducing a specialized convenience wrapper such as useEntityMutation:

Thank you for sharing the full context and your thoughts process. It really helps to understand how you arrived at the final proposal and more importantly leaves a great archive that we can use in the future when evolving all those APIs around entities.

@adamziel
Copy link
Contributor Author

I like the idea, but I don't find the API to be very intuitive if I'm honest. That is, when I read the code, I don't instantly know what it will do. What do you think about a param?

I like it much better @noisysocks, thank you! I just updated this PR accordingly.

Thank you for sharing the full context and your thoughts process. It really helps to understand how you arrived at the final proposal and more importantly leaves a great archive that we can use in the future when evolving all those APIs around entities.

My pleasure @gziolo ! I suspected that sharing just the final conclusion wouldn't be quite enough to explain the rationale here, I'm glad that was useful! I might start doing it more often when reasonable 🤔

@adamziel adamziel added the Needs Dev Note Requires a developer note for a major WordPress release cycle label Mar 11, 2022
@adamziel adamziel changed the title Throwing actions for creating, deleting, and updating entity records [core-data] Exceptions support for saveEntityRecord and deleteEntityRecord actions Mar 11, 2022
@adamziel adamziel changed the title [core-data] Exceptions support for saveEntityRecord and deleteEntityRecord actions [core-data] throwOnError option for saveEntityRecord and deleteEntityRecord actions Mar 11, 2022
packages/core-data/CHANGELOG.md Show resolved Hide resolved
packages/core-data/src/actions.js Outdated Show resolved Hide resolved
packages/edit-widgets/src/store/actions.js Outdated Show resolved Hide resolved
@gziolo
Copy link
Member

gziolo commented Mar 11, 2022

Which doesn't do much for creating and removing records, so we could also ditch these hooks and settle only for the useEntityRecordEdit hook:

const { editedRecord, applyEdits, saveEdits } = useEntityRecordEdit();

We can also expose applyEdits and saveEdits methods from the existing useEntityRecord. I bet editedRecord is already there.

I guess for create and delete dispatching actions as presented in this PR in most cases is enough.

@adamziel
Copy link
Contributor Author

The e2e failures are unrelated to this PR, see https://core.trac.wordpress.org/ticket/55367

@@ -70,6 +70,7 @@ _Parameters_
- _query_ `?Object`: Special query parameters for the DELETE API call.
- _options_ `[Object]`: Delete options.
- _options.\_\_unstableFetch_ `[Function]`: Internal use only. Function to call instead of `apiFetch()`. Must return a promise.
- _options.throwOnError_ `[boolean]`: If false, this action suppresses all the exceptions.
Copy link
Member

@gziolo gziolo Mar 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside: I think @michalczaplinski raised it in other places that it's confusing that the same APIs are documented in two places - here and in docs/reference-guides/data/data-core.md.

It'd be a good follow-up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix is beyond this PR, but I fully agree

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up = new PR. So we are on the same page 😄

@adamziel adamziel force-pushed the propose/use-entity-record-crud branch from 291d425 to 1b92f4d Compare March 14, 2022 14:27
Copy link
Member

@kevin940726 kevin940726 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good! Just a small concern regarding falsy error values.

@@ -273,6 +275,10 @@ export const deleteEntityRecord = (
error,
} );

if ( error && throwOnError ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if error is undefined or null or 0 or any falsy value? Even though it's an edge case, it should still throw such error 😅. I guess we'll need a flag like hasError to determine if it reaches the catch clause or not.
(Would be awesome if there's a test case for it too, but it's a nitpick.)

Copy link
Member

@kevin940726 kevin940726 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@adamziel adamziel force-pushed the propose/use-entity-record-crud branch 2 times, most recently from b9104fb to ab24ce7 Compare March 16, 2022 15:35
@adamziel adamziel force-pushed the propose/use-entity-record-crud branch from ab24ce7 to 8561fc9 Compare March 16, 2022 16:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Dev Note Requires a developer note for a major WordPress release cycle [Package] Core data /packages/core-data [Type] Code Quality Issues or PRs that relate to code quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants