Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

panthro's avatar

exclude certain fields conditionally on a API resource

In my API resource, along with other fields, I return a user resource like this:

....
'user' => new UserResource($this->whenLoaded('user')),
'start_date' => $this->when($this->start_date, $this->start_date),
 'end_date' => $this->when($this->end_date, $this->end_date),
....

But sometimes I do not want to include all the user's data. if it were a collection I could do:

'media' => MediaResource::collection($this->whenLoaded('media'))->except('some_field')

How can I exclude certain fields conditionally on a API resource?

0 likes
23 replies
panthro's avatar

@Sinnbeck no, I want to exclude fields on the UserResource which is a subset of the resource fields shown in my example.

Sinnbeck's avatar

@panthro then do it in that resource? Can you show the resource if you are in doubt (and an example of what should be hidden by what)

1 like
panthro's avatar

@Sinnbeck I don't want to do it in that resource. For example, a user resource should return everything for the user, but when a user is loaded on a related model such as a post, I want to exclude items such as the related users email.

.... Other fields
'user' => new UserResource($this->whenLoaded('user')), // the related model resource - exclude `email` required
'start_date' => $this->when($this->start_date, $this->start_date), // a field on the `post` resource
 'end_date' => $this->when($this->end_date, $this->end_date),
.... Other fields
Sinnbeck's avatar

@panthro Untested, but you could perhaps try something like this

'user' => collect(new UserResource($this->whenLoaded('user'))->toArray($request))-only(['name'])->toArray(),
1 like
panthro's avatar

@Sinnbeck nice idea, but fails when the relationship is not loaded (what the $this->whenLoaded is for).

Sinnbeck's avatar

@panthro Above the code..

if (! $this->resource->relationLoaded('user')) {
          $user = null;
} else {
   $user = new UserResource($this->resource->{$relationship}->only(['name']));
}
1 like
Sinnbeck's avatar

Or

'user' => new UserResource($this->whenLoaded('user', function() {
       return this->resource->user->only(['name']);
}),
1 like
panthro's avatar

this was for your first response, I will now try your second response - thanks!

panthro's avatar

With this:

'user' => new UserResource($this->whenLoaded('user'), function () {
                dd('i never die!');
            }),

Seems like fnc never called as it never dies.

Sinnbeck's avatar

Oops. Remove the )

$this->whenLoaded('user', function
1 like
panthro's avatar

@Sinnbeck yes I can now die.

But same error Attempt to read property \"username\" on array

I suspect what is happening, we are filtering the user correctly and only returning one field, but when its wrapped in the UserResource, it's looking for all of the other fields and failing:

UserResource:

 public function toArray($request)
    {
        return [
            'username' => $this->when($this->username, $this->username),
            'email' => $this->when($this->email, $this->email),
            'url' => $this->when($this->url, $this->url),
            'bio' => $this->when($this->bio, $this->bio),
            .....

Sinnbeck's avatar

@panthro do a dd() on what you have in the function and post it

'user' => new UserResource($this->whenLoaded('user', function() {
       dd(this->resource->user);
}),
1 like
panthro's avatar

@Sinnbeck I get the user model:

App\Models\User {#1402
  #fillable: array:6 [
    0 => "username"
    1 => "email"
    2 => "password"
    3 => "url"
    4 => "bio"
    5 => "newsletter_opt_in_at"
  ]
....

This:

dd($this->resource->user->only('username'));

Gives:

array:1 [
  "username" => "camron08"
]
Sinnbeck's avatar

@panthro Try this

dd($this->resource->user->makeHidden(['password', 'email']));
1 like
panthro's avatar

@Sinnbeck returns the user model, with those fields under hidden

App\Models\User {#1402
  #fillable: array:6 [
    0 => "username"
    1 => "email"
    2 => "password"
    3 => "url"
    4 => "bio"
    5 => "newsletter_opt_in_at"
  ]
  #hidden: array:5 [
    0 => "email"
    1 => "password"
    2 => "remember_token"
    3 => "password"
    4 => "email"
  ]

If you do this in the fnc:

$this->resource->user->makeHidden(['password', 'email']);

return $this->resource->user;

The email address is still returned.

Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

@panthro Ok this then

'user' => new UserResource($this->whenLoaded('user', function() {
       $user = $this->resource->user;
$fake = new User;
$fake->username = $user->username;
return $fake;
}),
1 like

Please or to participate in this conversation.