Home > other >  How to pass conditional variabiles to Laravel Blade Component
How to pass conditional variabiles to Laravel Blade Component

Time:12-24

I have a blade component for password fields and this is how I pass my information:

<x-store.password-field
     label="Password"
     name="password"
     placeholder="••••••••"
     error="Error message"
/>

As you can see, I have a variabile called error in order to display an error message if available. Now, I know how to display it in the page:

@error('password')
    {{ $message }}
@enderror

Is there a way to add this logic directly in the component so it should be something like if $error then add error="$message" to the component? The example below will not work but it's just for illustration to show you what I mean:

<x-store.password-field
     label="Password"
     name="password"
     placeholder="••••••••"
     @error('password') error="{{ $message }}" @enderror
/>

CodePudding user response:

Without going too much into details I wold like to describe who Laravel validation works. So this way I believe everything makes more sense. So when Laravel validates a form based on the rules you have set, it knows what kind of data it is expecting and if there are invalid data provided an ValidationException will be thrown. This

Illuminate\Validation\ValidationException.php

class has all these methods and properties. But I will mention the errorBag property that holds the error messages. So the exception obj($e) have access to all the error messages. If you do not take the responsibility to handle this exception, Laravel will do the handling as well. There is an

Illuminate\Foundation\Exceptions\Handler.php

class and you can see how it is handled in details. But shortly this is where the exception is converted to http response, by default it redirects back, and there are two other method called withInput and withErrors. Both of these flash the data to the request session. So this way form input data and error messages are stored in the session and they can be retrieved anywhere from the application. As you may know retrieving data from the session can be performed using session() helper or Session facade or any other way. But for convenience Laravel provides helper method old() and in the other hand shares the $errors attribute to all the views. So old() is used to retrieve old from input data and $errors is an

Illuminate\Support\MessageBag.php

obj that provides some useful methods to retrieve validation errors. Well $errors is shared to all the views something we would do inside the AppServiceProvider like View::share('errors', session()->get('errors')); but instead of ServiceProvider Laravel has done it using middleware:

Illuminate\View\Middleware\ShareErrorsFromSession

. And that's because no matter if there are errors or not you don't have to test if $errors isSet etc.

Inside of any view file the $errors attribute is available as well as the old() method. So it's all set for you to use. Anyway how you decide to retrieve data from the session is is your choice, but since there are all these things provided as well as Laravel blade instead of:

<?php
  if($errors){
?>
 //do something
<?php
  }
?>

// Blade offers:
@if($errors->has('password'))
  //do something
@endif

// Or even more cleaner like:
@error('password')
  //do something
@enderror

Since $errors or MessageBag instance is shared to all the views, I don't think you would ever want to pass it like a prop. And that because you can access it directly from the component.

However if you want to send it as a component prop you could do it. But don't forget the $errors is a MessageBag object. As well every single input field can have more than one error message for example name can contain both 'Min length is two characters' and 'Name should contain only letters'. For this reason $errors->get('name') will return an array. Since $errors is an MessageBag instance there are useful methods like $errors->first('name'); that will return the first element on the array and that is the error message, in this case 'Min length is two characters'. I want to mention that the error messages may not be identically to the one Laravel provides. But just to show the point. So in your case try something like this:

<x-store.password-field
     label="Password"
     name="password"
     placeholder="••••••••"
     :error="$errors->first('password')"
/>

Notice that when the data you want to provide is not just a simple string, you should add : in front of the attribute name. Otherwise the content it will be considered as a string.

CodePudding user response:

What you can try is take a look inside your blade input component (components/input.blade.php). There you should be able to condition the variable $error with session.

  • Related