Laravel - Trying to get property "id" of non-object

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Laravel: Solving the "Trying to get property 'id' of non-object" Error in API Resources

As a senior developer working with the Laravel ecosystem, you frequently deal with data transformation and API responses using Eloquent models and Laravel Resources. When these systems start throwing cryptic errors like Trying to get property "id" of non-object, it often points to a fundamental misunderstanding of how objects are passed through the framework lifecycle.

This post dives deep into the specific issue you encountered—trying to access properties on a non-existent object within your BillingResource—and provides the correct, idiomatic Laravel solution. We will dissect why this happens and show you the best practices for correctly fetching and transforming data in your API endpoints.

Understanding the Root Cause: Model vs. ID

The error you are seeing stems from passing a raw scalar value (an integer ID) directly to your Resource class constructor instead of passing the actual Eloquent model instance.

Let's look at the problematic controller code snippet:

// Controller Snippet
public function showBilling($id)
{
     return new BillingResource($id); // <-- Problem here!
}

When you execute new BillingResource($id), the BillingResource attempts to access properties like $this->id inside its toArray() method. However, since you passed an integer ($id) instead of a fully hydrated Eloquent Billing model object, $this inside the resource is not an object that possesses an id property, leading straight to the ErrorException.

Laravel Resources are designed to operate on existing models. They expect an instance of the model class so they can access all associated data methods and properties safely.

The Correct Approach: Fetching the Model First

The correct pattern in Laravel is always to use Eloquent's query builder to retrieve the necessary data before passing it to your Resource. This ensures that the Resource receives a valid object, allowing it to correctly access its attributes.

Here is how you should refactor your controller method:

use App\Models\Billing; // Ensure you import your model
use App\Http\Resources\BillingResource;

public function showBilling($id)
{
    // 1. Retrieve the Billing model using the provided ID
    $billing = Billing::findOrFail($id);

    // 2. Return the Resource, passing the actual Model instance
    return new BillingResource($billing);
}

Deep Dive into the Refactoring

By changing the controller to fetch $billing first, you solve the error immediately:

  1. Controller: Now returns an object of type BillingResource, which is instantiated with a valid Billing model object.
  2. Resource (toArray): When $this->id is called within the resource, it successfully accesses the id property from the underlying Eloquent model instance, preventing the "non-object" error.

This pattern adheres to solid Object-Oriented Programming principles and is a core principle recommended by the Laravel team when building robust APIs, as highlighted on the official Laravel documentation.

Reviewing Your Resource Implementation

Your BillingResource implementation looks good for mapping data:

// BillingResource.php
public function toArray($request)
{
    return [
        'id' => $this->id, // Now $this is a valid model object
        'network' => $this->network,
        // ... other fields
        'created_at' => (string) $this->created_at,
        'updated_at' => (string) $this->updated_at
    ];
}

The casting you implemented for created_at and updated_at to strings is a good practice, ensuring that date/time objects are correctly serialized into JSON format. This method of mapping data is exactly what Laravel Resources are designed to facilitate, making your API clean and predictable.

Conclusion

The lesson here is simple but critical for any Laravel developer: When creating a Resource, always pass an Eloquent Model instance, not just a primitive ID. By following the standard flow—fetching the model via Eloquent first, and then passing that model to your Resource—you ensure type safety, maintainability, and eliminate common runtime errors. Embrace this pattern for building scalable and reliable APIs with Laravel.