-
Notifications
You must be signed in to change notification settings - Fork 221
Add withCategories and withAttributes HOCs #935
Conversation
assets/js/base/utils/errors.js
Outdated
// let <ApiErrorPlaceholder /> handle the message to display. | ||
apiMessage: null, | ||
}; | ||
const formatErrorMessage = ( error, messageProperty = 'frontendMessage' ) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it'd be useful to have a doc block here, especially for describing what messageProperty
is a reference to and acceptable values.
Also I'd be wary of getting to context specific with frontendMessage
string here. What about userFriendly
instead (I'm guessing the idea here is a non-dev type error message?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
frontendMessage
was referring to errors produced by the frontend, but not necessarily user-friendly. For example, a JS error.
I completely refactored that part of the code in 2ac40b0, let me know how it looks now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
frontendMessage was referring to errors produced by the frontend, but not necessarily user-friendly. For example, a JS error
That's a good argument for not using frontend
though as it's still ambiguous. In continuing with the intended purpose, I would expect it to be something like general
(for general JS error) as opposed to api
(for error in an api response).
I have some more feedback on the refactor in my review comments to be published soon (including a suggestion to continue iterating on it in a separate pull so we don't block this one).
@@ -5,11 +5,21 @@ import { __ } from '@wordpress/i18n'; | |||
import PropTypes from 'prop-types'; | |||
import { escapeHTML } from '@wordpress/escape-html'; | |||
|
|||
const getErrorMessage = ( { apiMessage, message } ) => { | |||
const getErrorMessage = ( { apiMessage, message, frontendMessage } ) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar comment here as I left elsewhere. I think frontendMessage
is too specific a variable name. I anticipate this may be a type of message left in non frontend contexts as well. Would userFriendlyMessage
or informalMessage
be a better fit here?
return apiFetch( { | ||
path: addQueryArgs( `${ ENDPOINTS.products }/categories`, { per_page: -1 } ), | ||
} ); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed in this pull, but with the number of blocks calling product categories, this seems like a good thing to move to a wp.data store so that blocks using categories can share what is retrieved. This will help with limiting the number of queries to the server (same for product attributes and product attribute terms). That's something I can do in a pull?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, sounds like a good idea! 🙂
Thanks for the review @nerrad. This is ready for another look. |
return { | ||
message: error.message, | ||
type: error.type || 'frontend', | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the direction with providing a "type" to the error. However:
- defaults vary in the logic. Why?
- any caught exception always defaults to
frontend
as the type. Why?
I'm not sure we've landed on a good api for error handling yet, but it probably should be iterated on in it's own pull.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rationale behind that was that an API error will be a Response
object, so it will have a json
method, while errors produced in the frontend will not have that method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, there's a bit of code smell here with the confusing logic. Let's iterate on this in a follow-up (not urgent).
assets/js/base/utils/errors.js
Outdated
// let <ApiErrorPlaceholder /> handle the message to display. | ||
apiMessage: null, | ||
}; | ||
const formatErrorMessage = ( error, messageProperty = 'frontendMessage' ) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
frontendMessage was referring to errors produced by the frontend, but not necessarily user-friendly. For example, a JS error
That's a good argument for not using frontend
though as it's still ambiguous. In continuing with the intended purpose, I would expect it to be something like general
(for general JS error) as opposed to api
(for error in an api response).
I have some more feedback on the refactor in my review comments to be published soon (including a suggestion to continue iterating on it in a separate pull so we don't block this one).
} | ||
|
||
onExpandAttribute( item ) { | ||
const ProductAttributeControl = ( { attributes, error, expandedAttribute, onChange, onOperatorChange, isLoading, operator, selected, termsAreLoading, termsList } ) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a long line and should be split into multiline arguments here. #
Also applies to other refactors to functional components.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does it sound installing prettier
and setting it as a pre-commit hook in a follow-up and dealing with these issues there? That's what we were using in WooCommerce Admin and seems like the kind of job better suited for a machine than for a human. 😄
|
||
onExpandAttribute( item ) { | ||
const ProductAttributeControl = ( { attributes, error, expandedAttribute, onChange, onOperatorChange, isLoading, operator, selected, termsAreLoading, termsList } ) => { | ||
const onExpandAttribute = ( item ) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be declared outside of the component otherwise the <SearchListItem />
will receive a new function on every re-render of this component. One of the gotchas of switching to functional components from a class component. It's okay when you're not passing the function through as a prop but it's being passed through as the value for the onSelect
prop here.
Of course, this may be a moot point because there are other places where there will always be a new reference passed through as a prop (see here) for example. So if we're fine with <SearchListItem />
always re-rendering when <ProductAttributeControl />
does, then we can just leave things as is I suppose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
onExpandAttribute
relies on the onChange
prop, so we would need to re-create the function anyway on every re-render with the new onChange
, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh right! yup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy with where this pull is at for now. Let's iterate on other feedback in their own pulls and 🚢 this.
return { | ||
message: error.message, | ||
type: error.type || 'frontend', | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, there's a bit of code smell here with the confusing logic. Let's iterate on this in a follow-up (not urgent).
This PR:
withCategories
andwithAttributes
HOC.Screenshots
How to test the changes in this Pull Request:
src/RestApi/Controllers/ProductCategories.php
modify this line with:src/RestApi/Controllers/ProductAttributes.php
modify this one with: