Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

noblemfd's avatar

Maatwebsite import on failure redirects to Login Page

In my Laravel-5.8, I am importing from Excel into database using Maatwebsites-3.1:

public function importGrade(Request $request){
    $request->validate([
        'file' => 'required|max:10000|mimes:xlsx,xls',
    ]);
  $path1 = $request->file('file')->store('import'); 
  $path=storage_path('app').'/'.$path1;  
  
        $import = new GradeLevelsImport;
        $import->import($path); 
        if ($import->failures()->isNotEmpty()) {
            Session::flash('error', $import->failures()); 
            return redirect()->route('hr.grades.index');   
        }            
         
        Session::flash('success', 'Grade Records Imported Successfully');
        return redirect()->route('hr.grades.index');              
} 

On failure, it redirects me to the Login Page. The problem is coming from here:

        if ($import->failures()->isNotEmpty()) {
            Session::flash('error', $import->failures()); 
            return redirect()->route('hr.grades.index');   
        }

Even when I changed it to:

        if ($import->failures()->isNotEmpty()) {
            Session::flash('error', $import->failures()); 
            return back();     
        }

And even when I used:

return back()->withFailures($import->failures()); 

The problem still persists.

How do I get it resolved?

Thanks

0 likes
38 replies
neilstee's avatar

@noblemfd you mean you are logged in then when you import Excel you are logged out and redirected to Login page?

1 like
noblemfd's avatar

@neilstee - I didn't log out. When I submitted import button, it redirects me to Login Page. That it, to login afresh.

But when I removed this:

    if ($import->failures()->isNotEmpty()) {
        Session::flash('error', $import->failures()); 
        return redirect()->route('hr.grades.index');   
    }

It didn't redirect to Login Page. But I need it to display list of failures.

1 like
noblemfd's avatar

@michaloravec - GradeLevelsImport is inside Imports folder. That's where I have the Maatwebsite Excel import code:

class GradeLevelsImport implements ToModel, WithHeadingRow, SkipsOnError, WithValidation, WithBatchInserts, SkipsOnFailure
{	
  public function model(array $row)
  {  
     $grade_data = [
        'grade_level_code'                  => $row['grade_level_code'] ?? '',
        'grade_level_name'                  => $row['grade_level_name'] ?? '',
        'company_id'                        => Auth::user()->company_id,
        'created_by'                        => Auth::user()->id,
        'created_at'                        => date("Y-m-d H:i:s"),
        'is_active'                         => 1,  
        
     ];         
    
    $grade = HrGrade::create($grade_data);        
   
  } 

  public function batchSize(): int
  {
     return 1000;
  }  

  public function headingRow(): int
  {
     return 1;
  } 
}
MichalOravec's avatar

All methods in interfaces (ToModel, WithHeadingRow, SkipsOnError, WithValidation, WithBatchInserts, SkipsOnFailure) must be implemented within a class.

1 like
neilstee's avatar

@noblemfd can you try

if ($import->failures()->isNotEmpty()) {
      return redirect()->route('hr.grades.index')->withFailures($import->failures());
}
neilstee's avatar

hmm calling the $import->failures()->isNotEmpty() seems the culprit here then

noblemfd's avatar

@neilstee - But when I dd('hello') inside it, it displays, Any other idea or method?

neilstee's avatar

try this instead

!empty($import->failures())
neilstee's avatar

oh so the condition is working fine.

then I guess passing the $import->failures seems the issue? can you try your old code but instead of passing $import->failures use some dummy string data.

noblemfd's avatar

@neilstee - How do you mean by this "instead of passing $import->failures use some dummy string data"

neilstee's avatar

I mean like this

        if ($import->failures()->isNotEmpty()) {
			// dd('test'); <- you said this is working so no problem on the if condition
			
            return redirect()->route('hr.grades.index'); // how about this?   
        }
noblemfd's avatar

@neilstee - return redirect()->route('hr.grades.index'); also works.

But I need to find a way to display the failures

noblemfd's avatar

@neilstee

if ($import->failures()->isNotEmpty()) {
  return redirect()->route('hr.grades.index')->with('errors', $import->failures);
}

I got the same error.

But when I did it this way

        try {
        $import = new GradeLevelsImport;
        $import->import($path); 
        Session::flash('success', 'Grade Records Imported Successfully');
        return redirect()->route('hr.grades.index');                    
        } catch (\Maatwebsite\Excel\Validators\ValidationException $e) {
             $failures = $e->failures();

             foreach ($failures as $failure) {
                 $failure->row(); // row that went wrong
                 $failure->attribute(); // either heading key (if using heading row concern) or column index
                 $failure->errors(); // Actual error messages from Laravel validator
                 $failure->values(); // The values of the row that has failed.
             }
            Session::flash('error', $import->failures()); 
            return redirect()->route('hr.grades.index');                  
        }

and I did this on the blade:

@if (Session::has('failures'))
<table class="table table-danger">
    <tr>
        <th>
            Row
        </th>
        <th>
            Attribute
        </th>
        <th>
            Error
        </th>
        <th>
            Value
        </th>            
    </tr>   
    @foreach(session()->get('failures') as $validation)
    <tr>
        <td>
            {{$evalidation->row() ?? '' }}
        </td>      
        <td>
            {{$validation->attribute() ?? '' }}
        </td>   
        <td>
            <ul>
                @foreach($validation->errors() as $e)
                <li>{{$e ?? '' }}</li>
                @endforeach
            </ul>
        </td>      
        <td>
            {{$validation->value()[$validation->attribute()] }}
        </td>              
    </tr>        
    @endforeach 
</table>        
@endif  

It's always showing his success message, Session::flash('success', 'Grade Records Imported Successfully');

Yet if fails. It didn't get to the failure side.

MichalOravec's avatar

I think it should be

Session::flash('error', $import->errors());
1 like
neilstee's avatar

and maybe share what's inside dd($import->failures());

noblemfd's avatar

@neilstee - dd($import->failures());

  #items: array:198 [▼
    0 => Maatwebsite\Excel\Validators\Failure {#1284 ▼
      #row: 2
      #attribute: "Grade Code"
      #errors: array:1 [▼
        0 => "The Grade Code has already been taken."
      ]
      -values: array:2 [▼
        "grade_code" => "CLX"
        "grade_name" => "Class 1"
      ]
    }
    1 => Maatwebsite\Excel\Validators\Failure {#1280 ▼
      #row: 3
      #attribute: "Grade Code"
      #errors: array:1 [▶]
      -values: array:2 [▶]
    }
    2 => Maatwebsite\Excel\Validators\Failure {#1276 ▶}
    3 => Maatwebsite\Excel\Validators\Failure {#1277 ▶}
neilstee's avatar

@noblemfd from what I suggested earlier that try to pass some test data like this

        if ($import->failures()->isNotEmpty()) {
            return redirect()->route('hr.grades.index')->with('failures', []);
        }

does this work?

noblemfd's avatar

@neilstee - The error is no more there. But it only displays the title of the errors, the content of the error not there.

Row       |    Attribute      |     Error        |    Value
neilstee's avatar

@noblemfd yes because you are not passing any. can you do this then:

if ($import->failures()->isNotEmpty()) {
      return redirect()->route('hr.grades.index')->with('failures', json_decode(json_encode($import->failures()), true));
}

Then on your blade file, change your variables to use array index instead of object property.

noblemfd's avatar

@neilstee - I really appreciate your effort. But now I got this error:

production.ERROR: Call to a member function row() on array

and it points to {{$validation->row() ?? '' }}

in

@if (Session::has('failures'))
<table class="table table-danger">
    <tr>
        <th>
            Row
        </th>
        <th>
            Attribute
        </th>
        <th>
            Error
        </th>
        <th>
            Value
        </th>            
    </tr>   
    @foreach(session()->get('failures') as $validation)
    <tr>
        <td>
            {{$validation->row() ?? '' }}
        </td>      
        <td>
            {{$validation->attribute() ?? '' }}
        </td>   
        <td>
            <ul>
                @foreach($validation->errors() as $e)
                <li>{{$e ?? '' }}</li>
                @endforeach
            </ul>
        </td>      
        <td>
            {{$validation->value()[$validation->attribute()] }}
        </td>              
    </tr>        
    @endforeach 
</table>        
@endif
neilstee's avatar

@noblemfd as I said earlier, you have to change the call on blade file.

From $validation->row()

it should be like this $validation['row']

MichalOravec's avatar

@noblemfd Do you understand what is an array, a collection or an object?

When you have this code

return redirect()->route('hr.grades.index')->with('failures', []);

It's pretty clear that you get only

Row       |    Attribute      |     Error        |    Value

Because you send an empty array.

I'm really surprised that you didn't get any progress as programmer for the last year...

I suggest you to find someone who finnish your project instead of you...

noblemfd's avatar

@michaloravec - You are too forward and harsh in your approach. I showed you my dd($import->failures());

It is not empty. It was @neilstee that suggested

return redirect()->route('hr.grades.index')->with('failures', []);

If you are not sure of something, be calm.

Thanks

1 like
neilstee's avatar

Calm down guys, we are trying to make ourselves to be better programmers here :)

@noblemfd I was actually surprised that you didn't get the point that I suggested on passing an empty array to the route that @michaloravec is pointing about. But I saw your effort when you implement the try and catch approach on the documentation so kudos on you.

@michaloravec I hope you can be kind to your words especially to those beginners/in need because that might demotivate them to work on themselves to strive to be better. We all started by not knowing something.

We are all learning here nonetheless not just to be a better programmer but to be a good person overall so let's all keep going :)

neilstee's avatar
neilstee
Best Answer
Level 34

@noblemfd you might have missed my previous reply but you can try to dd() the new value of $failures in your blade file. basically, we just transformed the object to an array that's why $validation->row() wouldn't work now.

I think it will be $validation['row'] instead but check what's inside the new $failures array

MichalOravec's avatar

@neilstee He is not beginner...

35 000 experience, 9 lesson completed and 0 best replies.

We have suggested to him so many times to learn something on Laracasts.

At least to watch the basic series https://laracasts.com/series/laravel-6-from-scratch

And he never did it.

He create almost every single day a thread about the basic issue.

So what can I say.

1 like

Please or to participate in this conversation.