Remove message from MessageBag
Asked Answered
C

3

6

How can I remove an error message from a MessageBag?

I've been trying to remove a specific element from the message array that MessageBag uses without any luck.

I'm getting the same error message twice.

@if($errors->has('undefined'))
    <div class="alert alert-warning">
    <button type="button" class="close" data-dismiss="alert">&times;</button>
    <h4>Failure.</h4>
        {{ $errors->first('undefined') }}
    </div>
    <?
        // $messages = $errors->getMessages();
        $messages = $errors->toArray();
        unset($messages['undefined']);
    ?>
@endif

@if($errors->any())
    <div class="alert alert-error">
    <button type="button" class="close" data-dismiss="alert">&times;</button>
    <h4>Error!</h4>
        {{ $errors->first() }}
    </div>
@endif

Edit

I have done something like this and it seems to work.

<?
    $messages = $errors->toArray();
?>

        @if(array_key_exists('undefined', $messages))
            <?
                $message_array = $messages['undefined'];
                $message = $message_array[0];
                unset($messages['undefined']);
            ?>

            <div class="alert alert-warning">
            <button type="button" class="close" data-dismiss="alert">&times;</button>
            <h4>Failure.</h4>
                {{ $message }}
            </div>
        @endif

        <?
            foreach ($messages as $error => $error_array) { 
        ?>
            <div class="alert alert-error">
            <button type="button" class="close" data-dismiss="alert">&times;</button>
            <h4>Error!</h4>
                {{ $error_array[0] }}
            </div>
         <?
            }
         ?>

But my question still remains? Why is this happening in first place?
Does it has to do with the Session? I know that the errors variable it is stored in the Session.

Cristincristina answered 3/9, 2013 at 12:20 Comment(0)
C
2

http://laravel.com/api/class-Illuminate.Support.MessageBag.html

Unfortunately, Laravel does not offer methods for removing errors from the MessageBag instance. What you can do is make the 'undefined' error a variable so it's not even in the MessageBag to begin with and just use similar logic to show/hide that.

return View::make('test.view')
        ->with('undefined', 'Something is undefined')
        ->withInput($input)->withErrors($validator);

Passing by reference example. You could potentially modify the MessageBag class to have it pass by reference but it would be hacky.

<?php
class foo 
{
    public $value = 42;

    public function &getValue() 
    {
        return $this->value;
    }
}

$obj = new foo;
$myValue = &$obj->getValue(); // $myValue is a reference to $obj->value, which is 42.
$myValue = 2;

echo $obj->getValue(); // prints the new value of $obj->value, i.e. 2.
?>

Notice the & prepended to both the function name and the call.

Conceive answered 3/9, 2013 at 20:38 Comment(9)
The code sample was just an example,I know I can overcome this by passing it to the view in a different way,my main point is how to remove a message from the MessageBag,and why this isn't possible since they are stored in an array. Thnx for the answer!Cristincristina
The messages are in an array within the MessageBag class, but unfortunately, it's protected. So I guess the true answer to your question would be to create a new class which extends MessageBag and include methods for directly managing the $messages array. Here's a good tutorial on extending classes in Laravel 4. fideloper.com/extend-request-response-laravelConceive
You can access the $messages array via the methods that the class provide to you. You can see both functions in my example. So I don't think it's the true answer to my question.Cristincristina
You can't access it. You are just making a copy of it and storing it. Making changes (unsetting) to the copy isn't going to change the original variable. That's why your second way works, because you are only using the copy.Conceive
Why are you saying that? Are you sure about it? I just saw the source file of MessageBag and it returns a reference to the messages array.Cristincristina
I'm looking at the source as well, specifically for the toArray() function which calls the getMessages() function which returns the array of messages, but not by reference. laravel.com/api/…Conceive
By what then? Unless I'm missing something big, what you are saying doesn't make sense. It return a reference to messages array return $this->messages;. Why are you thinking it returns a copy;Cristincristina
It's not returning a reference because it's not passing it by reference. It's just creating a copy of the original variable. Maybe this will help you understand at what must be done to pass by reference. php.net/manual/en/language.references.return.php I've also updated the answer with a better example tailored to this specific scenario.Conceive
OK, that was very revealing! Coming from Java I didn't know that array is treated this way in PHP!! You can see here why. ideone.com/aVIC0d Thnx for insisting. Although your answer was not very informative your comments were! +1 I'll consider to accept your answer I think you deserve it!Cristincristina
T
5

I had the same issue, knowing that I can re-create the MessageBag and also access the errors of the current MessageBag with ->getMessages(). All I did was:

$validationErrors = $validator->errors()->getMessages();
unset($validationErrors['email']);
unset($validationErrors['phone_number']);

$newValidationErrors = new MessageBag($validationErrors);

I hope this helps

Tallyho answered 8/6, 2019 at 9:16 Comment(1)
Is it possible to assign the new MessageBag to the original validator? $validatorCoralline
H
3

I opened a PR for this and it was merged. As of Laravel 10, a forget method was added to the MessageBag and you can do:

$validationErrors = $validator->errors();
$validationErrors->forget('key');
Houle answered 10/2, 2023 at 15:2 Comment(0)
C
2

http://laravel.com/api/class-Illuminate.Support.MessageBag.html

Unfortunately, Laravel does not offer methods for removing errors from the MessageBag instance. What you can do is make the 'undefined' error a variable so it's not even in the MessageBag to begin with and just use similar logic to show/hide that.

return View::make('test.view')
        ->with('undefined', 'Something is undefined')
        ->withInput($input)->withErrors($validator);

Passing by reference example. You could potentially modify the MessageBag class to have it pass by reference but it would be hacky.

<?php
class foo 
{
    public $value = 42;

    public function &getValue() 
    {
        return $this->value;
    }
}

$obj = new foo;
$myValue = &$obj->getValue(); // $myValue is a reference to $obj->value, which is 42.
$myValue = 2;

echo $obj->getValue(); // prints the new value of $obj->value, i.e. 2.
?>

Notice the & prepended to both the function name and the call.

Conceive answered 3/9, 2013 at 20:38 Comment(9)
The code sample was just an example,I know I can overcome this by passing it to the view in a different way,my main point is how to remove a message from the MessageBag,and why this isn't possible since they are stored in an array. Thnx for the answer!Cristincristina
The messages are in an array within the MessageBag class, but unfortunately, it's protected. So I guess the true answer to your question would be to create a new class which extends MessageBag and include methods for directly managing the $messages array. Here's a good tutorial on extending classes in Laravel 4. fideloper.com/extend-request-response-laravelConceive
You can access the $messages array via the methods that the class provide to you. You can see both functions in my example. So I don't think it's the true answer to my question.Cristincristina
You can't access it. You are just making a copy of it and storing it. Making changes (unsetting) to the copy isn't going to change the original variable. That's why your second way works, because you are only using the copy.Conceive
Why are you saying that? Are you sure about it? I just saw the source file of MessageBag and it returns a reference to the messages array.Cristincristina
I'm looking at the source as well, specifically for the toArray() function which calls the getMessages() function which returns the array of messages, but not by reference. laravel.com/api/…Conceive
By what then? Unless I'm missing something big, what you are saying doesn't make sense. It return a reference to messages array return $this->messages;. Why are you thinking it returns a copy;Cristincristina
It's not returning a reference because it's not passing it by reference. It's just creating a copy of the original variable. Maybe this will help you understand at what must be done to pass by reference. php.net/manual/en/language.references.return.php I've also updated the answer with a better example tailored to this specific scenario.Conceive
OK, that was very revealing! Coming from Java I didn't know that array is treated this way in PHP!! You can see here why. ideone.com/aVIC0d Thnx for insisting. Although your answer was not very informative your comments were! +1 I'll consider to accept your answer I think you deserve it!Cristincristina

© 2022 - 2024 — McMap. All rights reserved.