Laravel 5 Collections: Convert Collection Elements Into Object Instances With mapInto

3 min read

The mapInto method is similar to the transform method in that allows you to quickly convert, or project, the contents of the collection to a new type. However, instead of building up the resulting type instance yourself, the mapInto method creates a new instance of the specified class and supplies each collection element's value and key as the arguments to the type's constructor.

Signature

public function mapInto(
    $class
);

Example Use

In the following example, we will take advantage of The Open Movie Database (OMDb) API (learn more about this API and get an API key at https://www.omdbapi.com/) to retrieve information above movie titles. We will do this with the following API wrapper class:

The app/Movie.php Class:

class Movie {

    /**
     * The title of the movie.
     *
     * @var string
     */
    protected $title = '';

    /**
     * The OMDB API key.
     *
     * @var string
     */
    private $omdbApiKey = '';

    /**
     * The API base URL.
     *
     * @var string
     */
    private $baseUrl = 'https://www.omdbapi.com/' .
                       '?t=<TITLE>&apiKey=<KEY>';

    /**
     * Indicates whether or the results
     * have been fetched from the API.
     *
     * @var bool
     */
    private $retrievedResults = false;

    /**
     * The results of the API call.
     *
     * @var null|array
     */
    private $apiResults = null;

    public function __construct($title)
    {
        $this->title = $title;
    }

    /**
     * Gets the API URL for the configured
     * key and movie title.
     *
     * @return string
     */
    private function getUrl() {
        return strtr($this->baseUrl, [
            '<TITLE>' => $this->title,
            '<KEY>'   => $this->omdbApiKey
        ]);
    }

    /**
     * Retrieves the API results if they
     * have not already been fetched.
     */
    private function checkResults() {
        if ($this->retrievedResults === false) {
            $apiResponse = with(new GuzzleHttp\Client)
                    ->get($this->getUrl());

            $this->apiResults = json_decode(
              $apiResponse->getBody(), true
            );

            $this->retrievedResults = true;
        }
    }

    function __get($name)
    {
        // This will let us "lazy-load" the API results.
        if ($this->apiResults == null ||
            array_key_exists(
                $name,
                $this->apiResults) === false) {
            return null;
        }

        return $this->apiResults[$name];
    }

}

In order to follow along, you will need to sign up for a free API key at https://www.omdbapi.com/apikey.aspx. Once you have an obtained an API key, you will need to set the $omdbApiKey private property of the Movie class.

While the Movie class may look complicated, we are simply issuing a GET request to the OMDb API and providing a proxy to the API results. We can use the mapInto collection method to convert a collection of movie titles into a Movie instance which will let us gather more information about each of the movies:

$movies = collect([
    'The Great Outdoors',
    'Uncle Buck'
])->mapInto(Movie::class)->each(function ($movie) {
   echo $movie->Title . ' ('. $movie->Year, ')<br />';
});

After the above code has executed in a browser, we would see results similar to the following:

The Great Outdoors (1988)
Uncle Buck (1989)

Comments

There are no comments. Be the first to comment!

Up next