Walid Ammar
Walid Ammar

Reputation: 4126

Laravel Session Flash persists for 2 requests

Recently I have changed to Laravel from Codeigniter, everything was going fine except I encountered a problem with Session::flash.

when I create new user I get success message but It will persist for 2 requests, even I didn't pass the validator: enter image description here

my code in UsersController:

function getCreateUser(){
    $config = array(
        'pageName' => 'createUser',
        'pageTitle' => 'Create User',
        'formUrl'   => action('UsersController@postCreateUser'),
        'modelFields'   => array(
            array('db_name' => 'employee_id', 'text' => 'Employee Id', 'mandatory' => TRUE),
            array('db_name' => 'full_name', 'text' => 'Full Name', 'mandatory' => TRUE),
            array('db_name' => 'email', 'text' => 'Email', 'mandatory' => FALSE),
            array('db_name' => 'password', 'text' => 'Password','value' => '12345', 'mandatory' => TRUE)
            ),
        'submit_text' => 'Create'
        );
    return View::make('layouts.form', $config);
}

function postCreateUser(){
    $config = array(
        'pageName' => 'createUser',
        'pageTitle' => 'Create User',
        'formUrl'   => action('UsersController@postCreateUser'),
        'modelFields'   => array(
            array('db_name' => 'employee_id', 'text' => 'Employee Id', 'mandatory' => TRUE),
            array('db_name' => 'full_name', 'text' => 'Full Name', 'mandatory' => TRUE),
            array('db_name' => 'email', 'text' => 'Email', 'mandatory' => FALSE),
            array('db_name' => 'password', 'text' => 'Password','value' => '12345', 'mandatory' => TRUE)
            ),
        'submit_text' => 'Create'
        );
    $validator = User::validate(Input::all());
    if($validator->passes()){
        $user = new User(Input::all());
        $user->password = Hash::make(Input::get('password'));
        $user->Company_id = '1';
        $user->save();

        Session::flash('message', 'User Created Successfully!'); 
        Session::flash('alert-class', 'alert-success');
        return View::make('layouts.form', $config);
    } 

    return View::make('layouts.form', $config)->withErrors($validator->messages());
}

in form.blade:

@if ( $errors->count() > 0 )
<div class="alert alert-danger">
    <p>The following errors have occurred:</p>

    <ul>
        @foreach( $errors->all() as $message )
        <li>{{ $message }}</li>
        @endforeach
    </ul>
</div>
@endif

in master.blade:

@if(Session::has('message'))
<p class="alert {{ Session::get('alert-class', 'alert-info') }} alert-dismissable"> {{ Session::get('message') }}</p>
@endif

Maybe I'm not alone with this issue, here is another unanswered question.

Update

For anyone in future facing this problem: Never flash session data without redirecting.

My code now looks like this:

function postCreateUser(){
    $validator = User::validate(Input::all());
    if($validator->passes()){
        $user = new User(Input::all());
        $user->password = Hash::make(Input::get('password'));
        $user->Company_id = '1';
        $user->save();

        Session::flash('message', 'User Created Successfully!'); 
        Session::flash('alert-class', 'alert-success');
    } else {
        Session::flash('message', Helpers::formatErrors($validator->messages()->all()));
        Session::flash('alert-class', 'alert-danger');
    }

    return Redirect::action('UsersController@getCreateUser');
}

Upvotes: 29

Views: 29557

Answers (7)

aross
aross

Reputation: 3606

The following seems to be available from version 5.1 onward. It used to be undocumented, now it is: see Laravel's session documentation.

session()->now()

This is the same as flash, except it won't persist to the next request.

Upvotes: 24

Rakeshkumar G G
Rakeshkumar G G

Reputation: 31

Check the scope of your Api's both session put and session get Api's have to be in same scope(i e web.php or api.php).

Upvotes: 0

Tjeu Moonen
Tjeu Moonen

Reputation: 317

create:

$request->session()->flash('status', 'Task was successful!');

delete:

$request->session()->forget('status');

Upvotes: 1

Drew
Drew

Reputation: 523

You are Flashing session data and creating a view instead of redirecting, meaning the message will Flash for this request and for the next one, showing twice.

If you want to show the message on the current request without redirecting, I would suggest providing the errors to your View::make instead of trying to Flash the messages. If you MUST Flash the message on the current request, then you will need to Session::forget('key') or Session::flush() after your view.

Upvotes: 32

AMIB
AMIB

Reputation: 3430

A good method to repopulate form with old data:

Controller:

View::make( 'view.name' )->withOldFormData( Input::all() );

View:

{{ Form::model( $old_form_data ) }}

Upvotes: -1

Timothy
Timothy

Reputation: 4285

As @Drew said earlier

You are Flashing session data and creating a view instead of redirecting, meaning the message will Flash for this request and for the next one, showing twice.

An easy way to flash a message once when you are creating a view is:

Session::flash($key, $value);
Session::push('flash.old', $key);

Happy coding!

Upvotes: 6

Neil Telford
Neil Telford

Reputation: 79

I had a similar problem, but I couldn't use Return::redirct, as I was using Ajax to to post to and from a within a set of Tabs.

Therefore, I was calling

Input::flashExcept('_token'); 

only if the validation failed and returning a view with the old input. Assuming validation passed and I wanted to run some functions and create a new view based on new data, I would call:

Session::forget('_old_input');  

I would put this before my final View::make

Hope this helps (or makes sense)...

Upvotes: 4

Related Questions