Collections | laravel-data | Spatie

 SPATIE

  Laravel Data
===============

spatie.be/open-source

  [Docs](https://spatie.be/docs)  [Laravel-data](https://spatie.be/docs/laravel-data/v1)  As-a-data-transfer-object  Collections

 Version   v4   v3   v2   v1

 Other versions for crawler [v4](https://spatie.be/docs/laravel-data/v4) [v3](https://spatie.be/docs/laravel-data/v3) [v2](https://spatie.be/docs/laravel-data/v2) [v1](https://spatie.be/docs/laravel-data/v1)

- [ Introduction ](https://spatie.be/docs/laravel-data/v1/introduction)
- [ Support us ](https://spatie.be/docs/laravel-data/v1/support-us)
- [ Requirements ](https://spatie.be/docs/laravel-data/v1/requirements)
- [ Installation &amp; setup ](https://spatie.be/docs/laravel-data/v1/installation-setup)
- [ Questions and issues ](https://spatie.be/docs/laravel-data/v1/questions-issues)
- [ Changelog ](https://spatie.be/docs/laravel-data/v1/changelog)
- [ About us ](https://spatie.be/docs/laravel-data/v1/about-us)

Getting started
---------------

- [ Quickstart ](https://spatie.be/docs/laravel-data/v1/getting-started/quickstart)

As a DTO
--------

- [ Creating a data object ](https://spatie.be/docs/laravel-data/v1/as-a-data-transfer-object/creating-a-data-object)
- [ Nesting ](https://spatie.be/docs/laravel-data/v1/as-a-data-transfer-object/nesting)
- [ Collections ](https://spatie.be/docs/laravel-data/v1/as-a-data-transfer-object/collections)
- [ Casts ](https://spatie.be/docs/laravel-data/v1/as-a-data-transfer-object/casts)
- [ From a request ](https://spatie.be/docs/laravel-data/v1/as-a-data-transfer-object/request-to-data-object)

As a resource
-------------

- [ From data to resource ](https://spatie.be/docs/laravel-data/v1/as-a-resource/from-data-to-resource)
- [ Transforming data ](https://spatie.be/docs/laravel-data/v1/as-a-resource/transformers)
- [ Lazy properties ](https://spatie.be/docs/laravel-data/v1/as-a-resource/lazy-properties)

Advanced usage
--------------

- [ Eloquent casting ](https://spatie.be/docs/laravel-data/v1/advanced-usage/eloquent-casting)
- [ Transforming to TypeScript ](https://spatie.be/docs/laravel-data/v1/advanced-usage/typescript)
- [ Creating a cast ](https://spatie.be/docs/laravel-data/v1/advanced-usage/creating-a-cast)
- [ Creating a transformer ](https://spatie.be/docs/laravel-data/v1/advanced-usage/creating-a-transformer)
- [ Creating a rule inferrer ](https://spatie.be/docs/laravel-data/v1/advanced-usage/creating-a-rule-inferrer)
- [ Internal structures ](https://spatie.be/docs/laravel-data/v1/advanced-usage/internal-structures)
- [ Validation attributes ](https://spatie.be/docs/laravel-data/v1/advanced-usage/validation-attributes)

      You are viewing the documentation for **an older version** of this package. You can check the version you are using with the following command:

 `                                    composer show spatie/laravel-data                                                                                                                                                                                                                                    `

Collections
===========

###  On this page

1. [ Creating ](#content-creating-datacollections)
2. [ Typing data within your collections ](#content-typing-data-within-your-collections)

The package provides next to the `Data` class also a `DataCollection` class. This collection can store a set of data objects, and we advise you to use it when storing a collection of data objects within a data object.

For example:

```
class AlbumData extends Data
{
    public function __construct(
        public string $title,
        /** @var SongData[] */
        public DataCollection $songs,
    ) {
    }
}
```

Using `DataCollection`s is required for internal state management within the data object, which will become clear in the following chapters.

Creating `DataCollection`s
----------------------------------------------------------------------------------------------------------------------------------

There are a few different ways to create a `DataCollection`:

```
SongData::collection([
    ['title' => 'Never Gonna Give You Up', 'artist' => 'Rick Astley'],
    ['title' => 'Giving Up on Love', 'artist' => 'Rick Astley'],
]);
```

If you have a collection of models, you can do the following:

```
SongData::collection(Song::all());
```

It is also possible to pass in a paginated collection:

```
SongData::collection(Song::paginate());
```

It is even possible to add a collection of data objects:

```
SongData::collection([
    SongData::from(['title' => 'Never Gonna Give You Up', 'artist' => 'Rick Astley']),
    SongData::from(['title' => 'Giving Up on Love', 'artist' => 'Rick Astley']),
]);
```

A `DataCollection` just works like a regular array:

```
$collection = SongData::collection([
    SongData::from(['title' => 'Never Gonna Give You Up', 'artist' => 'Rick Astley'])
]);

// Count the amount of items in the collection
count($collection);

// Changing an item in the collection
$collection[0]->title = 'Giving Up on Love';

// Adding an item to the collection
$collection[] = SongData::from(['title' => 'Never Knew Love', 'artist' => 'Rick Astley']);

// Removing an item from the collection
unset($collection[0]);
```

It is even possible to loop over it with a foreach:

```
foreach ($songs as $song){
    echo $song->title;
}
```

Typing data within your collections
-----------------------------------------------------------------------------------------------------------------------------------------------------------------

When nesting a data collection into your data object, always type the kind of data objects that will be stored within the collection:

```
class AlbumData extends Data
{
    public function __construct(
        public string $title,
        /** @var SongData[] */
        public DataCollection $songs,
    ) {
    }
}
```

Because we typed `$songs` as `SongData[]`, the package automatically knows it should create `SongData` objects when creating an `AlbumData` object from an array.

There are quite a few ways to type data collections:

```
// Without namespace

/** @var SongData[] */
public DataCollection $songs;

// With namespace

/** @var \App\Data\SongData[] */
public DataCollection $songs;

// As an array

/** @var array */
public DataCollection $songs;

// As a data collection

/** @var \Spatie\LaravelData\DataCollection */
public DataCollection $songs;

// With an attribute

#[DataCollectionOf(SongData::class)]
public DataCollection $songs;
```

You're free to use one of these annotations/attributes as long as you're using one of them when adding a data collection to a data object.
