Neeraj1005's avatar

ErrorException Undefined index: name http://acl.test/newsletter/imports

In my project I've used the https://github.com/maatwebsite/Laravel-Excel package for importing the data. The problem I am facing that: If I upload correct file with correct header or row data File succesfully uploaded. But if I put wrong file with wrong data it sends me an error.

Can anyone tells me how can I validate the proper validation for csv If i put wrong file then it show me an error?

Import File

<?php

namespace App\Imports;

use App\Newsletter;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithValidation;

class NewsletterImport implements ToModel, WithHeadingRow, WithValidation
{
    /**
    * @param array $row
    *
    * @return \Illuminate\Database\Eloquent\Model|null
    */
    public function model(array $row)
    {
        return new Newsletter([
            'name'     => $row['name'],
            'email'    => $row['email'],
            'token'    => Str::random(60),
        ]);

    }

    public function rules(): array
    {
        return [
            '*.name' => ['name', 'unique:newsletters,name'],
            '*.email' => ['email', 'unique:newsletters,email'],
        ];
    }
}

Rules

 public function rules()
    {
        return [
            'import_file' => 'required|file|mimes:csv,txt,xls',
        ];
    }

Export Controller

 public function store(NewsletterImportRequest $request)
    {
        if ($request->hasFile('import_file')) {
            $import_file = $request->file('import_file');
        }

        Excel::import(new NewsletterImport, $import_file);

        return back()->withMessage('file successfully imported');
    }

0 likes
1 reply
MarianoMoreyra's avatar

Hi @neeraj1005

I've made a helper function for those cases as I had several imports for one client:

public function validateHeaders($valid, $imported)
{
    if($imported->diffAssoc($valid)->count() > 0) 
    {
        foreach($imported->diffAssoc($valid) as $field) {
            $errors[$field] = "Wrong header: ".$field." (valid headers: ".implode(", ", $valid).")";
        }
        throw ValidationException::withMessages($errors);
    }

    return true;
}

Then, at each Import Class I define an array with valid headers and pass it as well as the heading row to my helper function:

private $headers = ['product_name', 'description', 'notes', 'team'];

public function collection(Collection $rows)
{
    validateHeaders($this->headers, $rows[0]->keys());

    // rest of your code
}

The helper function will throw a custom ValidationException so it will behave the same as the rest of the validations.

As you can see, in my case I use it with ToCollection importers instead of ToModel, but in case you don't want to change to ToCollection, I guess you can import the headings row as suggested here to pass it to check against your valid ones: https://docs.laravel-excel.com/3.1/imports/heading-row.html#importing-only-the-heading-row

Hope this helps!

1 like

Please or to participate in this conversation.