get_php_workin
get_php_workin

Reputation: 450

How to submit a form with Vuejs to use Laravel Controller

I have a vuejs component that acts as my login form and I am trying to passing in the form through a Laravel controller similar to how you would do it in blade.php <from method="POST" action="login"> and in web.php Route::post('/login', 'LoginController@login').

Where LoginController should simply redirect to a new view (testing):

class LoginController extends Controller {

    public function login() {
        
        return view( 'home' )
    }
}

The issue is that while the form does get submitted and gets passed in the controller, the entire home.blade.php html gets loaded back as response data and not as a new 'home.blade.php' view.

Here is the vuejs login component:

<template>
        <div id="form-input">
            <form method="POST" @submit.prevent="login" :class="{ 'disable-interaction' : submitted }">
                <input class="single-line-input" placeholder="Email" type="text" name="email" v-model="form.email">
                <input class="single-line-input space" placeholder="Password" type="password" name="password" v-model="form.password">
                <div class="large bottom">
                    <p v-if="error" class="error large">{{ error }}</p>
                    <button class="large btn-important" type="submit">sign in</button>
                    <a class="large btn-important-inverted" href="register">register</a>
                    <a class="simple-link center" v-bind:href="back">back</a>
                </div>
            </form>
        </div>
</template>

<script>
    export default {
        props: {
            error: String,
            back: String
        },

        data: function() {
            return {
                submitted: false,
                form: {
                    email: '',
                    password: ''
                }
            }
        },

        methods: {
            login: function() {
                this.submitted = true;
                axios.post('login', this.form)
                    .then(res => console.log(this.form))
                    .catch(err => console.log(err));
                this.submitted = false;
            }
        }
    }
</script>

Which I simply call in login.blade.php:

@extends('layouts.auth')

@section('form')
    <login-form 
        error="{{ isset($error) }}"
        back="{{ url('home') }}" 
    ></login-form>
@endsection

And in my web.php:

Route::get('/login', function () { return view('auth.login'); });
Route::post('/login', 'LoginController@login');

Upvotes: 1

Views: 5742

Answers (2)

Peppermintology
Peppermintology

Reputation: 10210

The issue is that while the form does get submitted and gets passed in the controller, the entire home.blade.php html gets loaded back as response data and not as a new 'home.blade.php' view.

Well yeah, because you're not performing any logic, you're just returning a view.

public function login()
{
    // thanks for submitting the form, have a view
    return view('home');
}

Authenticate your User then redirect them if authentication is successful, otherwise return an authentication failure message.

public function login()
{
    // authenticate user
    if ($auth->fails()) {
        return response()->json(['success' => false, 'errors' => []], 401);
    }

    return redirect(route('home'));
}

Your home route will do what your GET login route currently does and just return view('home');

Upvotes: 1

lyyka
lyyka

Reputation: 560

You must take care on what you are doing where in your application.

You should NEVER render a view inside a controller method that is called by POST. POST means that you will only do something with the data and it usually redirects the user to some other GET route (dashboard i.e.)

In your case, what you should do inside a login() function is just to authenticate the user using the data you sent with your axios request. login() function will automatically accept Request $request argument as it is a POST request.

You can get email and password out of the request by doing $credentials = $request->only(['email', 'password']); and then use Laravel's Auth facade to authenticate the user with Auth::attempt($credentials);. Read more about Laravel Auth here.

Based on the return value of Auth::attempt() and if authentication was successful or not, you should return a JSON response back to your vue app. Read how to do that here.

From there, when you catch the response in then() method, you read the response and see if authentication was successful or not. Based on the result redirect your app accordingly. Here is how to do redirects in vue app.

If you plan your whole app to be in Vue, you can consider building Vue SPA (Single Page Application) and use Vue-Router instead of Laravel's routing and blade components.

Upvotes: 0

Related Questions