hotwired / turbo-ios

iOS framework for making Turbo native apps
MIT License
874 stars 88 forks source link

Double request when submitting a form via a modal #186

Closed joemasilotti closed 5 months ago

joemasilotti commented 6 months ago

When submitting a form in a modal the redirected to page is requested twice.

  1. Run the turbo-native-demo web app locally
  2. Open Demo.xcodeproj and change Demo.current to return local
  3. Run the app and tap "Load a web page modally"
  4. Tap "Submit form"
  5. The form dismisses

Expected behavior

  1. One request is made to /success

Actual behavior

  1. Two requests are made to /success
➜  turbo-native-demo git:(main) npx nodemon
[nodemon] 2.0.22
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node server.js`
Server is listening on port 45678
Thu Feb 29 2024 05:02:56 GMT-0800 (Pacific Standard Time) -- GET /
Thu Feb 29 2024 05:02:57 GMT-0800 (Pacific Standard Time) -- GET /npm/@hotwired/stimulus@3.2.2/+esm
Thu Feb 29 2024 05:03:01 GMT-0800 (Pacific Standard Time) -- GET /new
Thu Feb 29 2024 05:03:01 GMT-0800 (Pacific Standard Time) -- GET /npm/@hotwired/stimulus@3.2.2/+esm
Thu Feb 29 2024 05:03:11 GMT-0800 (Pacific Standard Time) -- POST /new
Thu Feb 29 2024 05:03:11 GMT-0800 (Pacific Standard Time) -- GET /success
Thu Feb 29 2024 05:03:11 GMT-0800 (Pacific Standard Time) -- GET /success

If the /success page were to show a confirmation flash message via a Rails flash, then the user would never see it. The first request would "eat" it and it would never be shown on the second one.


Session seems to think this request is the user navigating "backwards", the second request triggering from this line:

extension Session: VisitableDelegate {
    public func visitableViewWillAppear(_ visitable: Visitable) {
        guard let topmostVisit = self.topmostVisit, let currentVisit = self.currentVisit else { return }

        if visitable === topmostVisit.visitable && visitable.visitableViewController.isMovingToParent {
            // Back swipe gesture canceled
            if topmostVisit.state == .completed {
                currentVisit.cancel()
            } else {
                visit(visitable, action: .advance)
            }
        } else if visitable === currentVisit.visitable && currentVisit.state == .started {
            // Navigating forward - complete navigation early
            completeNavigationForCurrentVisit()
        } else if visitable !== topmostVisit.visitable {
            // Navigating backward
            visit(visitable, action: .restore) // THIS LINE
        }
    }
}

This issue is fixed via #155.

jayohms commented 5 months ago

Resolved in https://github.com/hotwired/turbo-ios/pull/155