Skip to content
New issue

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

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

Already on GitHub? # to your account

Use effect to place order after details have been fetched. #2486

Merged
merged 7 commits into from
Jun 16, 2020

Conversation

sirugh
Copy link
Contributor

@sirugh sirugh commented Jun 11, 2020

Description

The invoker returned as const [getOrderDetails] = useLazyQuery is not actually a promise as we previously believed. We want to only place the order once the order details have been fetched. The code was causing a race condition because both operations were happening at the same time.

Related Issue

Closes PWA-677.

Acceptance

Verification Stakeholders

Specification

Verification Steps

  1. Place an order.
  2. Make sure the page doesn't flicker between cart, loading, and the receipt page.
  3. In the network tab, ensure that the "place order" mutation was not made until the "getOrderDetails" query completes.

Screenshots / Screen Captures (if appropriate)

Image from Gyazo

Checklist

  • I have added tests to cover my changes, if necessary.
  • I have updated the documentation accordingly, if necessary.

@PWAStudioBot
Copy link
Contributor

PWAStudioBot commented Jun 11, 2020

Fails
🚫 A version label is required. A maintainer must add one.
Messages
📖

Access a deployed version of this PR here. Make sure to wait for the "pwa-pull-request-deploy" job to complete.

📖 DangerCI Failures related to missing labels/description/linked issues/etc will persist until the next push or next nightly build run (assuming they are fixed).
📖

Associated JIRA tickets: PWA-677.

Generated by 🚫 dangerJS against dda8b8a

@devops-pwa-codebuild
Copy link
Collaborator

devops-pwa-codebuild commented Jun 11, 2020

Performance Test Results

The following fails have been reported by WebpageTest. These numbers indicates a possible performance issue with the PR which requires further manual testing to validate.

https://pr-2486.pwa-venia.com : LH Performance Expected 0.85 Actual 0.57, LH Best Practices Expected 1 Actual 0.92
https://pr-2486.pwa-venia.com/venia-tops.html : LH Performance Expected 0.75 Actual 0.36, LH Best Practices Expected 1 Actual 0.92
https://pr-2486.pwa-venia.com/valeria-two-layer-tank.html : LH Performance Expected 0.8 Actual 0.49, LH Accessibility Expected 0.9 Actual 0.89, LH Best Practices Expected 1 Actual 0.92

jimbo
jimbo previously approved these changes Jun 11, 2020

if (!placeOrderLoading && !hasError && orderDetailsData) {
if (orderNumber) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Makes sense. 👍

// Fetch order details and then use an effect to actually place the
// order. If/when Apollo returns promises for invokers from useLazyQuery
// we can just await this function and then perform the rest of order
// placement.
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, the Apollo docs say the following about the invoker:

Function that can be triggered to execute the suspended query. After being called, useLazyQuery behaves just like useQuery.

So I think they do intend for us to use called, data, and loading as returned by the hook, since they're updated by the hook itself as part of its internal lifecycle. And if we want to use the hook's return values, we have to do it as an effect, just as you've done here.

revanth0212
revanth0212 previously approved these changes Jun 12, 2020
@revanth0212
Copy link
Contributor

Other than test failures, code looks fine.

}

if (orderDetailsData && !placeOrderCalled) {
placeOrderAndCleanup();
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this not be await placeOrderAndCleanup()?

Copy link
Contributor

Choose a reason for hiding this comment

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

Should this not be await placeOrderAndCleanup()?

The function provided to useEffect isn't an async function, so we couldn't await this call.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope - this is the pattern for writing effects that contain async code. You can't have a top level await because the callback passed to useEffect cannot be asynchronous itself.

@dpatil-magento
Copy link
Contributor

QA Pass, good to merge after test changes and approval.

Signed-off-by: sirugh <rugh@adobe.com>
@sirugh sirugh dismissed stale reviews from revanth0212 and jimbo via c67073c June 12, 2020 19:03
@@ -146,7 +147,8 @@ const getTalonProps = props => {
* beforeAll
*/

beforeAll(() => {
beforeEach(() => {
jest.clearAllMocks();
Copy link
Contributor

Choose a reason for hiding this comment

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

This shouldn't be necessary, since we do this at the config level.

@dpatil-magento dpatil-magento merged commit 4def22a into develop Jun 16, 2020
@dpatil-magento dpatil-magento deleted the rugh/pwa-677-place-order-race-condition branch June 16, 2020 15:25
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants