#How to properly do this with Inertia.js?

1 messages · Page 1 of 1 (latest)

terse adder
#

I have an application where an authenticated user can push a button to show a modal. The modal prompts the user to select which version of an application they want to fill out (versionA or versionB). Upon selecting one of the options, a draft record is created and they are redirected to the edit view for that form. Happy path, life is good.

Now if the user has already created one of these forms, they are not allowed to create another one. Instead they need to edit their existing application or delete their old application and there is a process for completing this task on the same page.

What I want: When the user tries to create a second new application by clicking the buttons for application versionA or versionB, it should close the existing modal and open another modal explaining that they need to edit their existing record or delete their existing record before creating a new one.

#

Currently I handle this logic by flashing a variable called $hasExistingApplication = true like so

if ($existingApplication) {
            return redirect()->route('dashboard')->with([
                'hasExistingApplication' => true,
            ]);
        }

and then in my frontend code .

const createApplication = (type) => {
    router.post('/applications', { type }, {
        onSuccess: (page) => {
            if (page.props.flash && page.props.flash.hasExistingApplication) {
                applicationSelectionModalOpen.value = false;
                // Code to show other modal telling user to edit existing application or delete it
            }
        },
        ...
    });
}

Right now this variable gets flashed using the HandleInertiaRequests middleware. However this means it gets shared with every page which seems odd to me.

I could add logic to only show the hasExistingApplications variable if it exists like so

$flashData = [];

        if ($request->session()->has('hasExistingApplication')) {
            $flashData['hasExistingApplication'] = fn () => $request->session()->get('hasExistingApplication');
        }

This approach seems kind of clunky although it works. Is there a simpler approach for this kind of logic that I'm just not thinking of? Perhaps a way without this type of flash message handling.

If I wasn't using Inertia, it seems like my logic would be something like. Have a controller method to checkExistingApplication, send back a json response, based on that json response, do "X" or "Y". However, within an Inertia application, you need to send back Inertia responses.

terse adder
#

Trying to analyze possible approaches:

  1. Use onSuccess and onError to establish different actions or logic paths
  2. Use Shared Flash Messaging to pass data for use in application logic
  3. Make AJAX Requests - though allowed, not the idiomatic way of doing things with Inertia.
  4. Manual Visit - visit a route then do something like this
router.get('/some/endpoint')
  .then(page => {
    if (page.props.someConditionOrData) {
      // Do something based on props
    }
  });
  1. ....Am I missing other approaches?

Maybe I should be solving my question using point 4 listed here instead of flash messaging?

inner coyote
#

Funny, I also had a similar issue (though much simpler) where multiple modals meant adding unnecessary complexity that would otherwise be solved easily with a single API call. I ended up using dedicated pages for everything just like a regular server side app would do, since ultimately the purpose of the SPA is to give the illusion that things are happening fast and snappy.

#

One other option that you may consider is using a multi-step approach, where the warning message remains hidden unless the user tries to do an invalid action.

#

If everything goes well the user is redirected to another page, so no harm done there. If not, the modal remains open but slides to reveal the error message. This could be a component that loads lazily since it won't always be necessary. But this implies an AJAX request.

#

I have a feeling that option 3 is your best option here. There's nothing wrong with making network requests to retrieve data. Just because you're not going through Inertia doesn't mean is not idiomatic since Inertia only serves as the glue between the two layers, but you would still reach for AJAX calls for other things like search functionality.

terse adder
#

@inner coyote Having a hidden error message on the selection modal itself might be a slightly better user experience vs having another modal pop up. Good point.

terse adder