Laravel: Display of validation errors not shown - laravel

I'm having a problem viewing validation errors in the blade view; this is the code below.
Controller (ClientController)
public function store(Request $request) {
$request->validate([
'name' => 'required',
'surname' => 'required',
'diagnosis' => 'required',
]);
Client::create([
'name'=>$request->name,
'surname'=>$request->surname,
'city'=>$request->city,
'diagnosis'=>$request->diagnosis,
]);
return redirect(route('client.index'))->with('message','The customer was successfully saved');
}
View (client.create)
<x-layout>
<div class="container">
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<form action="{{route('client.store')}}" method="post">
#csrf
<div class="row mt-3">
<div class="col-12 col-md-6">
<div class="mb-3">
<label for="name" class="form-label">Nome</label>
<input type="text" class="form-control p-3" name="name" required>
</div>
<div class="mb-3">
<label for="surname" class="form-label">Cognome</label>
<input type="text" class="form-control p-3" name="surname" required>
</div>
<div class="col-12">
<div class="mb-3">
<label for="diagnosis" class="form-label">Diagnosi</label>
<input type="text" class="form-control p-3" name="diagnosis" required>
</div>
</div>
<button type="submit" class="btn btn-primary mb-5 py-3 px-5 mt-3 ms-3">Add</button>
</div>
</div>
</form>
</div>
</x-layout>
I have followed the documentation but am unable to understand where the problem is.
Laravel documentation
Thanks to those who will help me
CONTROLLER UPDATE:
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
return view('client.create');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$request->validate([
'name' => 'required',
'surname' => 'required',
'diagnosis' => 'required',
]);
//dd($request->all());
Client::create([
'name'=>$request->name,
'surname'=>$request->surname,
'city'=>$request->city,
'diagnosis'=>$request->diagnosis,
'stay'=>$request->stay
]);
return redirect(route('client.index'))->with('message','The customer was successfully saved');
}
Index is a blade view that contains the customer table (this works fine).
The problem is the error messages I would like to see in the create view if an input is required and not compiled

So after checking all components, it has been under our nose the whole time.
All your inputs have the required attribute:
<div class="mb-3">
<label for="name" class="form-label">Nome</label>
<input type="text" class="form-control p-3" name="name" required>
</div>
<div class="mb-3">
<label for="surname" class="form-label">Cognome</label>
<input type="text" class="form-control p-3" name="surname" required>
</div>
<div class="col-12">
<div class="mb-3">
<label for="diagnosis" class="form-label">Diagnosi</label>
<input type="text" class="form-control p-3" name="diagnosis" required>
</div>
</div>
This way the request is not sent, because the browser actively needs to fulfil all requirements to start the request to client.create
If you would remove one of these attributes and then not fill it in and submit, it will cause the errors to show.
However, we concluded that it is better to keep the required attribute in, as it is better to prevent a call to the webserver than to only let laravel do the work of validation.
The laravel validation is more useful for ajax/api calls, where there is no frontend to prevent you from making the request, like this:
//required jquery
$.ajax({
url: '/your/url/here',
method: 'POST',
data: [
name: 'somename',
surname: 'somesurname',
],
success(response) {
console.log('Yay, it succeeded')
},
error(error) {
//I havent worked with jquery in a while, the error should be in error object
console.log(error);
}
})
Or how I like to do it in vue, with axios:
//requires axios
axios
.post('/url/here', {
surname: 'somesurname',
diagnosis: 'somediagnosis',
})
.then(response => {
console.log('Yay, it succeeded')
})
.catch(error => {
console.log('Error', error)
})
You can see in the last two examples, as there is no frontend to prevent this request from being made, you now at least make sure laravel is not going to run it's logic with missing variables, which would cause a crash.

Related

Laravel 8 Form Request Validation Redirect to Index page instead same page and show error

On localhost all is good, but when I deploy the application to the server not working. If form request validation fails instead of bringing me back to the same page and showing an error, it redirects me to the index page.
config.blade.php
<form method="POST" action="{{ route('config.update', $config->id) }}">
#csrf
#method('PUT')
<div class="form-group row">
<div class="col">
<label class="col-form-label">Name</label>
<input id="name" type="text" class="form-control" name="name" value="{{ $config->name }}" required>
</div>
</div>
<div class="form-group row mt-3">
<div class="col">
<label class="col-form-label text-md-right">Address</label>
<input id="address" type="text" class="form-control" name="address" value="{{ $config->address }}">
</div>
</div>
<div class="form-group row mt-3">
<div class="col">
<label class="col-form-label text-md-right">Phone</label>
<input id="phone" type="tel" class="form-control" name="phone" value="{{ $config->phone }}" required>
</div>
</div>
<div class="form-group row mt-3">
<div class="col">
<label class="col-form-label text-md-right">E-mail</label>
<input id="email" type="email" class="form-control" name="email" value="{{ $config->email }}" required>
</div>
</div>
<div class="form-group row mt-4 mb-0">
<div class="col-md-12">
<button type="submit" class="btn btn-primary button-full-width">Save changes</button>
</div>
</div>
</form>
web.php
Route::resource('/admin/config', 'Admin\ConfigController');
ConfigController
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Services\ConfigServices;
use App\Http\Requests\ConfigRequest;
use App\Models\Config;
class ConfigController extends Controller
{
protected $configServices;
public function __construct(ConfigServices $configServices) {
$this->middleware('auth');
$this->configServices = $configServices;
}
...
public function update(ConfigRequest $request, $id)
{
$config = $this->configServices->updateConfigById($request, $id);
return redirect()->back();
}
...
}
ConfigRequest - here is the problem
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ConfigRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => 'required|string|max:255',
'address' => 'nullable|string|max:255',
'phone' => 'required|regex:/^([0-9\s\-\+\(\)]*)$/|min:9|max:15',
'email' => 'required|email:rfc',
];
}
}
Form Request return to index page instead same page. On localhost working everything, but when I deploy the app to server a problem arises.
When data on form request validated correct return me back on the same page and show success, but when form request failing redirect mine for some reason to the index page.
A problem arises in Laravel 8, this code worked well in previous Laravel versions.
Can someone help me, please?
In your custom request you need:
/**
* The URI that users should be redirected to if validation fails.
*
* #var string
*/
protected $redirect = '/dashboard';
or
/**
* The route that users should be redirected to if validation fails.
*
* #var string
*/
protected $redirectRoute = 'dashboard';
You can find more in the docs.
In the docs for older versions of Laravel these properties don't exist.
Do you have error parts in your blade?
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#if ($message = Session::get('unique'))
asdsad
#endif
#endforeach
</ul>
</div>
#endif

Axios returning HTML in response instead of data

I want to ask for help regarding Axios' response to my POST request in the login route via Laravel. It returns HTML of the homepage in data when it authenticated the user (or it finds the user in the database). Please see the response screenshot below:
May I just ask for the solution to my problem? Here are the necessary codes and the versions that I am using:
Tools
VueJS: v3.0.5
Axios: 0.19
Laravel: 5.8
Codes
Login.vue (script)
import axios from 'axios'
export default {
data() {
return {
csrfToken: '',
loginObj: {
username: '',
password: '',
remember: false,
},
message: '',
}
},
created() {
this.csrfToken = document.querySelector('meta[name="csrf-token"]').content;
},
methods: {
signIn() {
console.log(this.loginObj)
axios.post('login', this.loginObj).then(res => {
console.log(res)
})
.catch(error => {
console.log(error.response)
})
}
}
}
Login.vue (template)
<div class="card shadow-lg border-0 rounded-lg mt-5">
<div class="card-header bg-orange"><h3 class="text-center my-4">Hello!</h3></div>
<div class="card-body p-0">
<div class="row">
<div class="col-lg-6 d-none d-lg-block">
<div class="login-image-wrap text-center">
<img src="/img/ahrs_logo_trans.png" class="login-img" alt="AKB Logo">
</div>
</div>
<div class="col-lg-6">
<div class="p-5">
<div class="text-center">
<h1 class="h4 text-gray-900 mb-4">Sign In</h1>
</div>
<form name="loginForm" #submit.prevent="signIn">
<input type="hidden" name="_token" :value="csrfToken">
<div class="form-group">
<label class="small mb-1" for="inputUsername">Username</label>
<input class="form-control py-4" v-model="loginObj.username" id="inputUsername" type="text" placeholder="Enter username" required autofocus>
</div>
<div class="form-group">
<label class="small mb-1" for="inputPassword">Password</label>
<input class="form-control py-4" v-model="loginObj.password" id="inputPassword" type="password" placeholder="Enter password" required>
</div>
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="remember" id="remember" v-model="loginObj.remember">
<label class="form-check-label text-small" for="remember">
Remember Me
</label>
</div>
</div>
<div class="form-group d-flex align-items-center justify-content-between mt-4 mb-0">
<a class="small" href="password.html">Forgot Password?</a>
</div>
<hr />
<div>
<button type="submit" class="btn bg-yellow btn-block font-weight-bold">LOGIN</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
LoginController.php
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
// override in the AuthenticatesUsers function username()
public function username()
{
return 'username';
}
Thank you for your help.
You will probably need to tell Laravel that you want to return the User as JSON if it's an ajax request.
You can do this by adding the following to your LoginController:
protected function authenticated(Request $request, $user)
{
if ($request->ajax()) {
return $user;
}
}
You may also need to set the X-Requested-With header that is usually set in the default bootstrap.js file that comes with Laravel so that Laravel knows it's an ajax request:
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
Obviously, if this line is already there and you're still including the bootstrap file in your bundle you can ignore this.

Why am getting method not allowed error when saving the data in Laravel?

In my application, I am getting the error method not allowed when trying to save the data. I am posting my codes here, please someone look into this and help me.
HolidayAdd.vue
<template>
<layout>
<form #submit.prevent="handleSubmit">
<div class="input-group">
<div class="input-group-prepend">
<span for="name" class="input-group-text">First Name and Last Name </span>
</div>
<input type="text" class="form-control" name="firstname" placeholder="Enter your First Name" v-model="holiday.fname" id="fname">
<input type="text" class="form-control" name="lastname" placeholder="Enter your Last Name" v-model="holiday.lname" id="lname">
</div>
<br>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">Start Date </span>
</div>
<input type="date" class="form-control" name="startdate" v-model="holiday.sdate" id="sdate">
</div>
<br>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">End Date</span>
</div>
<input type="date" class="form-control" name="enddate" v-model="holiday.edate" id="edate">
</div>
<br>
<button type="submit" class="btn btn-info">Apply</button>
</form>
</layout>
</template>
<script>
import Layout from './../../Shared/Layout'
export default {
components: {
Layout
},
data() {
return {
holiday: {
fname: '',
lname: '',
sdate: '',
edate: ''
}
}
},
methods: {
async handleSubmit() {
let response = await this.$inertia.post('/holiday/store', this.holiday)
}
}
}
</script>
HolidayController.php
public function store(Request $request)
{
$holiday = $request->validate([
'firstname' => 'required',
'lastname' => 'required',
'startdate' => 'required',
'enddate' => 'required'
]);
Holiday::create($holiday);
return redirect()->route('holiday.index')->with('success', 'Record Inserted Successfully');
}
web.php
Route::resource('holiday', 'HolidayController');
As far as I know, there is no error, then why I am getting a 405 error here?
In your Vue code your should use POST request to the '/holiday' instead of the '/holiday/store'.
Defining resource route is equivalent to:
Route::get('/holiday', 'HolidayController#index');
Route::get('/holiday/create', 'HolidayController#create');
Route::post('/holiday', 'HolidayController#store');
Route::get('/holiday/{holiday}', 'HolidayController#show');
Route::get('/holiday/{holiday}/edit', 'HolidayController#edit');
Route::put('/holiday/{holiday}', 'HolidayController#update');
Route::patch('/holiday/{holiday}', 'HolidayController#update');
Route::delete('/holiday/{holiday}', 'HolidayController#destroy');
https://laravel.com/docs/5.8/controllers#resource-controllers
Your url '/holiday/store' dose not much Route::resource('holiday', 'HolidayController');
Fix
await this.$inertia.post('holiday', this.holiday)
To check routes and its corresponding URIs
Run the following command
php artisan route:list

PUT/POST in Laravel

I'm brand new to Laravel and am working my way through the [Laravel 6 from Scratch][1] course over at Laracasts. The course is free but I can't afford a Laracasts membership so I can't ask questions there.
I've finished Section 6 of the course, Controller Techniques, and am having unexpected problems trying to extend the work we've done so far to add a few new features. The course has students build pages that let a user show a list of articles, look at an individual article, create and save a new article, and update and save an existing article. The course work envisioned a very simple article containing just an ID (auto-incremented in the database and not visible to the web user), a title, an excerpt and a body and I got all of the features working for that, including updating an existing article and saving it.
The update form sets method to POST but then uses a #METHOD('PUT') directive to tell the browser that it is actually supposed to do a PUT. This worked perfectly in the original code. However, now that I've added two more fields to the form, when I click Submit after editing an existing record, the save fails with this message:
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
The PUT method is not supported for this route. Supported methods: GET, HEAD, POST.
http://localhost:8000/articles
I don't understand why adding two fields to the form would cause this to break. Can someone enlighten me? I added the two new fields/columns to the migration and ran migrate:rollback and migrate. I've also added the new fields/columns to the fillable attribute and added validations for them in the ArticlesController.
Here is my routing:
Route::get('/articles', 'ArticlesController#index');
Route::post('/articles', 'ArticlesController#store');
Route::get('/articles/create', 'ArticlesController#create');
Route::get('/articles/{article}', 'ArticlesController#show');
Route::get('/articles/{article}/edit', 'ArticlesController#edit');
Route::put('/articles/{article}', 'ArticlesController#update');
//Route::delete('/articles/{article}', ArticlesController#destroy');
This is my ArticlesController:
<?php
namespace App\Http\Controllers;
use App\Article;
use Illuminate\Http\Request;
class ArticlesController extends Controller
{
public function index()
{
$articles = Article::latest()->get();
return view ('articles.index', ['articles' => $articles]);
}
public function show(Article $article)
{
return view('articles.show', ['article' => $article]);
}
public function create()
{
return view('articles.create');
}
public function store()
{
//Stores a NEW article
Article::create($this->validateArticle());
return redirect('/articles');
}
public function edit(Article $article)
{
return view('articles.edit', ['article' => $article]);
}
public function update(Article $article)
{
//Updates an EXISTING article
$article->update($this->validateArticle());
return redirect('/articles/', $article->id);
}
public function validateArticle()
{
return request()->validate([
'title' => ['required', 'min:5', 'max:20'],
'author' => ['required', 'min:5', 'max:30'],
'photopath' => ['required', 'min:10', 'max:100'],
'excerpt' => ['required', 'min:10', 'max:50'],
'body' => ['required', 'min:50', 'max:500']
]);
}
public function destroy(Article $article)
{
//Display existing record with "Are you sure you want to delete this? Delete|Cancel" option
//If user chooses Delete, delete the record
//If user chooses Cancel, return to the list of articles
}
}
Here's my edit form, edit.blade.php:
#extends('layout')
#section('content')
<div id="wrapper">
<div id="page" class="container">
<h1>Update Article</h1>
<form method="POST" action="/articles">
#csrf
#method('PUT')
<div class="form-group">
<label class="label" for="title">Title</label>
<div class="control">
<input class="form-control #error('title') errorborder #enderror" type="text" name="title" id="title" value="{{ $article->title }}">
#error('title')
<p class="errortext">{{ $errors->first('title') }}</p>
#enderror
</div>
</div>
<div class="form-group">
<label class="label" for="author">Author</label>
<div class="control">
<input class="form-control #error('author') errorborder #enderror" type="text" name="author" id="author" value="{{ $article->author }}">
#error('title')
<p class="errortext">{{ $errors->first('author') }}</p>
#enderror
</div>
</div>
<div class="form-group">
<label class="label" for="photopath">Path to Photo</label>
<div class="control">
<input class="form-control #error('photopath') errorborder #enderror" type="text" name="photopath" id="photopath" value="{{ $article->photopath }}">
#error('title')
<p class="errortext">{{ $errors->first('photopath') }}</p>
#enderror
</div>
</div>
<div class="form-group">
<label class="label" for="excerpt">Excerpt</label>
<div class="control">
<textarea class="form-control #error('excerpt') errorborder #enderror" name="excerpt" id="excerpt">{{ $article->excerpt }}</textarea>
#error('excerpt')
<p class="errortext">{{ $errors->first('excerpt') }}</p>
#enderror
</div>
</div>
<div class="form-group">
<label class="label" for="body">Body</label>
<div class="control">
<textarea class="form-control #error('body') errorborder #enderror" name="body" id="body">{{ $article->body }}</textarea>
#error('body')
<p class="errortext">{{ $errors->first('body') }}</p>
#enderror
</div>
</div>
<div class="control">
<button class="btn btn-primary" type="submit">Submit</button>
</div>
</form>
</div>
</div>
#endsection
Is there anything else you need to see?
[1]: https://laracasts.com/series/laravel-6-from-scratch/episodes/33?autoplay=true
Your Laravel route is:
Route::put('/articles/{article}', 'ArticlesController#update');
So your form action url should match that uri:
<form action="{{ url('/articles/'.$article->id) }}">
where the {article} parameter is the record id (you can read more about in the docs here).
Then in your controller update() method, you have:
return redirect('/articles/', $article->id);
which means redirect to /articles with status code $article->id (you can read more about in the docs here). I think you are trying to redirect to the show route, which is:
Route::get('/articles/{article}', 'ArticlesController#show');
So change the , (comma) to a . (dot) to concatenate the article id with the uri:
return redirect('/articles/' . $article->id);
The route in the form for /articles, However your route for updating should be /articles/{article}
Try this:
<form method="POST" action="/articles/{{ $article->id }}">

Storing registration data in database using laravel 5.4

Have been trying to create a user registration/login page following laracast video.
But when I try to register a user, it return to the same page without given any error as to why. I also noticed that the supplied info is not stored in the database.
Am so confused I don't know what am doing wrong you help will be really appreciated
Here is my view:
<div class="col-md-offset-1 col-md-8">
<h1 class="text-center ">Register</h1>
<form method="POST" action="register" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" name="name" required>
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control" email="email" required>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" name="password" required>
</div>
<div class="form-group">
<label for="password_confirmation">Password Confirmation</label>
<input type="password" class="form-control" name="password_confirmation" required>
</div>
<button type="submit" class="btn btn-primary"><i class="fa fa-reply"></i>Register</button>
</form>
</div>
This is my controller
public function create()
{
return view('registration.create');
}
public function store(Request $request)
{
//validate form
$this->validate(request(),[
'name' => 'required',
'email' => 'required|email',
'password' => 'required|confirmed',
]);
//create and save user
$user = new User; //create new Post model object
$user->name = $request->name; //adding thing to the the Post object
$user->email = $request->email;
$user->password = $request->password;
//save user
$user->save(); //to save the new item into the DB
//$user = User::create(request(['name', 'email', 'password']));
//sign them in
auth()->login($user);
//redirect to the admin
return redirect('/admin');
}
While this is my route file:
Route::get('register', 'RegistrationController#create');
Route::post('register', 'RegistrationController#store');
Thanks a lot in advance
Check your form, there's an error in the email field. It says:
and should be:
<input type="email" class="form-control" name="email" required>
So, replace email="email" with name="email"
first you add this error block. so, you can find error easily.
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
Then, your mistake is in form action. please replace it to below code.
<form method="POST" action="{{ route('register') }}" enctype="multipart/form-data">

Resources