1

I'm not familiar with Vue.js at all, so found a good replacement using Livewire.

The challenge that I've got to solve is to have a user friendly registration on my website using Fortify + Livewire. The registration process is a multistep one and depends on the choices that the user makes it will load the relative fields.

So far I set up the Fortify views by adding in the FortifyServiceProvider.php file the following code:

Fortify::loginView(function () {
    return view('auth.login');
});

Fortify::registerView(function () {
    return view('auth.register');
});

The auth/login.blade.php view loading the livewire component which is basically a form:

<form action="{{ route('register') }}" method="POST" wire:submit.prevent="submit">
    /**
    * Here would go the inputs that must be shown depends on what users choice 
    * (is it an ordinar user or a company)
    */
    <button type="submit">Save<button/>
</form>

The multiform challenge would be resolved by adding $step property into the Register.php class:

class RegisterForm extends Component
{
    public $step;

    public function mount()
    {
        $this->step = 0;
    }

    public function submit()
    {
        if ($this->step < 3) {
            $this->step++;           
        } else {
            // pass all the data to the fortify register method
            // <-- Here is my trouble!
        }
    }
}

which will be incremented by passing each of the registration steps ($this->step++).

The most important thing that is quite complicated for me is how to prevent form submission to have the validation + form changes and by the end all the set of the data to pass trough Fortify registration process?

danplaton4
  • 119
  • 2
  • 14

4 Answers4

1

Look at the fortify Controller for register

public function store(Request $request, CreatesNewUsers $creator): RegisterResponse
    {
        event(new Registered($user = $creator->create($request->all())));
        $this->guard->login($user);
        return app(RegisterResponse::class);
    }

T

use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Facades\Auth;
use Laravel\Fortify\Contracts\CreatesNewUsers;
use Livewire\Component;

class Register extends Component
{
    public $name;
    public $email;
    public $password;
    public $password_confirmation;

    public function submit(CreatesNewUsers $creator)
    {
        event(new Registered($user = $creator->create([
            'name' => $this->name,
            'email' => $this->email,
            'password' => $this->password,
            'password_confirmation' => $this->password_confirmation,
        ])));

        Auth::guard()->login($user);

        $this->redirect('home');
    }

    public function render()
    {
        return view('livewire.register');
    }
}

Something like this will work for your use case.

You are still using the fortify Action and Still Firing the Event

  • If there are errors or exceptions raised in the registration process (e.g. the e-mail address is malformed, or the password doesn't meet the complexity requirement) how do we capture those errors? It seems that this code would just let the exceptions be thrown away. Meanwhile, the end-user interacting with the web-browser wouldn't see any response at all. – cartbeforehorse Aug 12 '21 at 22:07
0

The response is to use dependency injection by injecting the Fortify CreateNewUser action in the mounting method of the Livewire component.

use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Facades\Auth;
use App\Actions\Fortify\CreateNewUser;
use Livewire\Component;

class Register extends Component
{
    public $name;
    public $email;
    public $password;
    public $password_confirmation;
    
    protected $creator;

    public function mount(CreateNewUser $creator)
    {
        $this->creator = $creator;
    }

    public function submit()
    {
        event(new Registered($user = $this->creator->create([
            'name' => $this->name,
            'email' => $this->email,
            'password' => $this->password,
            'password_confirmation' => $this->password_confirmation,
        ])));

        Auth::guard()->login($user);

        $this->redirect('home');
    }

    public function render()
    {
        return view('livewire.register');
    }
}
Karl Hill
  • 12,937
  • 5
  • 58
  • 95
Manasse
  • 39
  • 7
0

The response is to use app container

<?php

use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Facades\Auth;
use App\Actions\Fortify\CreateNewUser;
use Livewire\Component;

class Register extends Component
{
    public $name;
    public $email;
    public $password;
    public $password_confirmation;
    


    public function submit()
    {
        event(new Registered($user = app(CreateNewUser::class)->create([
            'name' => $this->name,
            'email' => $this->email,
            'password' => $this->password,
            'password_confirmation' => $this->password_confirmation,
        ])));

        Auth::guard()->login($user);

        $this->redirect('home');
    }

    public function render()
    {
        return view('livewire.register');
    }
}
Manasse
  • 39
  • 7
-1

you can use blade example

@if($step > 3)
     <input name="name" type="text">
@endif
Abdulmajeed
  • 552
  • 7
  • 8
  • thanks for your answer. But that's not what I looked for. I was actually looking at how I can send this data to the fortify register process? – danplaton4 Oct 18 '20 at 08:26