0

I'm using Laravel 5.8 and I wanted to retrieve some data from an Api route:

Route::prefix('v1')->namespace('Api\v1')->group(function(){
    Route::get('/articles','ArticleController@index');;
});

Then I made a Resource Collection and a Controller as well:

ArticleCollection.php:

public function toArray($request)
    {
        return parent::toArray($request);
    }

ArticleController:

public function index()
    {
        $articles = Article::all();
        return new ArticleCollection($articles);
    }

Now it properly shows data:

{"data":[{"art_id":3,"art_cat_id":15,"art_author_id":23973,"art_title":"\u0627\u062d\u06cc\u0627\u06cc...

But when I change the Resource Collection to this:

public function toArray($request)
    {
        return [
            'title' => $this->art_title,
            'desc' => $this->art_description,
        ];
    }

And trying to find an specific article in the Controller:

public function index()
    {
        $articles = Article::find(1);
        return new ArticleCollection($articles);
    }

I will get this error somehow:

FatalThrowableError Call to a member function toBase() on null

So what's going wrong here? How can I solve this issue?

japose7523
  • 29
  • 2
  • 15
  • I think that because the first one, returns a collection of articles, and the second one returns a single item from the article collection. CMIIW – Farhan Muhammad Jun 29 '22 at 11:41
  • @FarhanMuhammad I did this by following a tutorial step by step! Then would you tell me how can I return the expected result properly? – japose7523 Jun 29 '22 at 12:00
  • What output that you expect? is that the same as the first one? – Farhan Muhammad Jun 29 '22 at 14:08
  • find() function will return the eloquent object, all() function will return the collection, then you convert that collection into an array. But the second one only return an object, not the collection, so it cannot be converted to an array just like the first one. If you need a single object as the second one, you only need to do like this $article = Article::find(1); // $article means single article, $articles is a collection of article (first one) return $article->toArray(); this to array will convert that object to an associative array based on the model attributes. – Farhan Muhammad Jun 29 '22 at 14:18

1 Answers1

0

Change this:

public function index()
    {
        $articles = Article::find(1);
        return new ArticleCollection($articles);
    }

to this:

public function index()
    {
        $articles = Article::where('id',1)->get();
        return new ArticleCollection($articles);
    }

This is because the find returns just one record and you are converting that to a collection, by using get() you can return a collection as you intend to here.

Salman Malik
  • 923
  • 6
  • 24
  • This cannot be the case, as laravel will convert the resource to collection if it isn't. [Refer to here](https://github.com/laravel/framework/blob/78eb4dabcc03e189620c16f436358d41d31ae11f/src/Illuminate/Http/Resources/Json/ResourceCollection.php#L38) – SEYED BABAK ASHRAFI Jul 04 '22 at 07:40
  • ```find()``` return collections only when there's multiple IDs supplied, or else it will supply Model or null. More details here: https://stackoverflow.com/a/27610932/12138592 – Salman Malik Jul 05 '22 at 09:27