Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QUESTION] Confusion About ToCollection concerns? #1999

Closed
nickpoulos opened this issue Jan 17, 2019 · 4 comments
Closed

[QUESTION] Confusion About ToCollection concerns? #1999

nickpoulos opened this issue Jan 17, 2019 · 4 comments
Labels

Comments

@nickpoulos
Copy link

Prerequisites

Versions

  • PHP version: 7.1.2
  • Laravel version: 5.7.1
  • Package version: 3.1.0

Description

The import functionality is not intuitive how it is all supposed to work together, and not documented well enough to alleviate the lack of intuition. I am confused as to what the point of a ToCollection concern is exactly?

I tried to setup a very simple toCollection import. I don't want the items actually stored in a database at the time of Excel file reading because I need to sum and run calculations on the data first, then pass it off to other objects that actually handle the importing and logging. I don't want a mega import class.
So I setup a simple Import using the toCollection concern, like so:

<?php

namespace App\Services\Revenue\ExcelImports;

use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;

class KargoImport implements ToCollection
{
    public function collection(Collection $rows)
    {
        return $rows->transform(function($row) {
           return [
               'date' => $row[0],
               'site' => $row[1],
               'impressions' => $row[2],
               'revenue' => $row[3]
           ];
        });
    }
}

Then I tried to import using:

$records = Excel::import(new KargoImport(), $filePath);

Which returns a MaatWebsiteExcel object that I can't seem to access the collection of data. And not even that, I stuck a DD in my collection() method of KargoImport, and the function doesn't even get hit?

So instead I tried:

$records = Excel::toCollection(new KargoImport(), $filePath);

That at least returned my data, but again, it was not run through the collections() function at all.

I get the same exact results when I pass in a null importer like so:

$records = Excel::toCollection(null, $filePath);

So that tells me for my purposes, the Importer is useless? But it doesn't seem it should be? I would think the first example, using the Excel::import() function with a ToCollection importer as param, would return the collection of rows already run through the Importer->collection() method. This would also allow me to use the other functions/traits for chunking reads and other functionality.

Additional Information

None

@patrickbrouwers
Copy link
Member

Import objects are there to encapsulate your import logic. You can add a lot of behaviour by using the other concerns.

Excel::toCollection() is a helper for people that want to have the entire collection where they want it. (e.g. controller).

using the Excel::import() function with a ToCollection importer as param, would return the collection of rows already run through the Importer->collection() method.

If you use ToCollection concern, you get the imported collection inside the collection() method. ::import() doesn't return the collection, it delegates the import action to the import object.

You have to use either ToCollection concern or ::toCollection() helper method. They are not meant to be combined.

I think the ToCollection documentation (https://laravel-excel.maatwebsite.nl/3.1/imports/collection.html) demonstrates the usage of it quite okay. The collection() method gets a Collection of all rows that are imported, you can then loop through them and e.g. insert them in the database.

@vesper8
Copy link

vesper8 commented Mar 25, 2019

@patrickbrouwers So how then do you actually accomplish what @nickpoulos wanted to do and what I want to do.

Which is to call a method that returns a collection that's been put through a transformer first and that's it, no models involved, just return a transformed collection from a .csv file.. seems like a simple enough task that this package should be able to handle easily

@vesper8
Copy link

vesper8 commented Mar 25, 2019

phew.. managed to get something working

in my controller:

        $import = new MyImport();
        Excel::import($import, $csvFile);
        dd($import->collection);

MyImport.php:

<?php

namespace App\Imports;

use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;

class MyImport implements ToCollection
{
    public $collection;

    public function collection(Collection $collection)
    {
        $this->collection = $collection->transform(function ($row) {
            return [
                'rank' => $row[0],
                'name' => $row[1],
            ];
        });
    }
}

@Rsagrawals
Copy link

@patrickbrouwers i am trying to use skierrors and skipfailure traits with tocollection but its not working. But with toModel its working fine. how can i skip errors in toCollection and collect them in the last?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants