When calling toArray() on an API Resource that uses the whenLoaded() helper method and that particular relation is not loaded, an ErrorException is thrown.
Trying to get property of non-object in ResourceCollection.php (line 48)
whenLoaded() helper method.toArray() method on the resource.I had a similar problem and I fixed it by wrapping all my custom code related to the relation inside the "relationLoaded" conditional, for example:
if ($this->relationLoaded('relation-name')) {
// call the toArray() method here
}
Despite being marked public, I don't believe resource toArray() methods were ever meant to be invoked in app code. The framework has no unit tests directly calling that method. There are only integrations tests making assertions on HTTP response JSON. The docs also don't demonstrate an example call to $resource->toArray($request): https://laravel.com/docs/5.7/eloquent-resources
Since the constructor of ResourceCollection never assigns a wrapped collection when MissingValue is passed in (for a relation not loaded), this would likely be the framework fix in your use case:
public function toArray($request)
{
if (! $this->collection) {
return [];
}
return $this->collection->map->toArray($request)->all();
}
But I don't see how that change could be covered by an integration test. ConditionallyLoadsAttributes already removes such a ResourceCollection item when resolving the HTTP response.
@derekmd is right. I don't think it's meant to be used like this.
For anyone still stumbling across this: Use $resource->resolve() instead of $resource->toArray(null). This works like a charm, even together with whenLoaded().
Most helpful comment
I had a similar problem and I fixed it by wrapping all my custom code related to the relation inside the "relationLoaded" conditional, for example: