-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Fixed errors when adding duplicate categories. #4372
Fixed errors when adding duplicate categories. #4372
Conversation
68ff60a
to
bc6291b
Compare
this.addRequest = new Model( { id: xhr.responseJSON.data } ).fetch(); | ||
return this.addRequest.then( resolve, reject ); | ||
// search the new category created since last fetch | ||
this.addRequest = new Model().fetch( |
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.
Why did you change the request here? Thinking that requesting using the id
is more reliable, isn't it?
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 bug was that the server when returns the 409 answer does not return the term. So we were generating an invalid request GET http://src.wordpress-develop.test/wp-json/wp/v2/categories/[object%20Object] 404 (Not Found). Requesting by id would be better but I think we can not do that because we don't know the id yet :(
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.
Did you try to inspect the 409
response? I think when I did this, the response body used to contain the conflicting id
.
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.
Yes I tried, and unfortunately, we are out of luck the response just contains "{"code":"term_exists","message":"A term with the name provided already exists with this parent.","data":{"status":409}}". Maybe something changed in the API meanwhile.
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.
But this means we may have an issue here, what guarantees that the received category is the right one? I think we should compare the name
once we retrieve the results instead of just picking the first one. Imagine two categories at the same level called "cat" and "cat 2", I believe if you try to insert "cat", the order is not guaranteed in the API response and we may insert "cat 2" instead right?
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.
Yes, you are right, we should add a client-side filter on the search results. I will make the change :)
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 change was applied, we should be handling all the cases now.
if ( formName === '' || adding ) { | ||
return; | ||
} | ||
|
||
// check if the term we are adding already exists | ||
const existingTerm = find( availableTerms, term => { |
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.
Noting that this doesn't fix the issue really because this will only search in the availableTerms locally which doesn't correspond to the whole list of terms.
I personally think we can't reliably fix this issue right now because there's no API to fetch the terms by "name" and "parent" (search is not perfect and could return results even if it's not a duplicate).
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 avoids making the request, if this fails and the category is not on the list, then we try to add if the server returns a 409 we are totally certain that a duplicate exists than we search for it, and we use the return of the search. The only case where we may fail is the search returns more than one term besides the duplicate, I will apply a client-side filter by name and parent on the search result this way we are certain we handle all cases.
Now before issuing requests to the server, we verify if the category being added already exists. If yes we try to select it (if it is not already select). If the category does exist we issue a request to the server, if we get an error saying we have a duplicate category (category may have been added by other used since last time we fetched), we search the server for the new category and we add it to our list.
bc6291b
to
3e569eb
Compare
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.
LGTM 👍
What about the non hierarchical selector, do we have a similar issue there?
Good point @youknowriad, I checked the code and we have the same problem there. I will address it in a new PR. |
if ( formName === '' || adding ) { | ||
return; | ||
} | ||
|
||
// check if the term we are adding already exists | ||
const existingTerm = this.findTerm( availableTerms, formParent, formName ); |
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.
Minor: Could this have been consolidated into the findOrCreatePromise
as an early return value for the term
argument of the resolved promise callback?
Now before issuing requests to the server, we verify if the category being added already exists. If yes we try to select it (if it is not already select).
If the category does exist we issue a request to the server, if we get an error saying we have a duplicate category (category may have been added by other used since last time we fetched), we search the server for the new category and we add it to our list.
JS errors are fixed, a 409 HTTP request may appear in the console but that is expected if the category was added in simulations since last time we fetched and we are handling that situation.
Fixes: #3910
How Has This Been Tested?
Add a category verify things work as expected.
Add a category that is repeated but not selected for the post, verify the category was selected and no error appeared in the console.
Open/create a new post, open another window with a different post, add a category in this new window. Go back to the first window, add the same category verify no error besides HTTP 409 appeared on the console and the category was added to the list of available categories.