Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add #[Required] attribute #9084

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

oli-laban
Copy link

1️⃣ Is this something that is wanted/needed? Did you create a discussion about it first?

It's something I'd personally find useful, and imagine others would too. No discussion though.

2️⃣ Did you create a branch for your fix/feature? (Main branch PR's will be closed)

Yes: required-attribute

3️⃣ Does it contain multiple, unrelated changes? Please separate the PRs out.

No, just this feature.

4️⃣ Does it include tests? (Required)

Yes

5️⃣ Please include a thorough description (including small code snippets if possible) of the improvement and reasons why it's useful.

Motivation

Due to the way attributes on Livewire components are set on the component's properties (i.e. not through a constructor), properties without default values can be left uninitialized if the corresponding attributes are missing from the component tag.

This can cause any number of different errors depending on how the property is used. Commonly something like:

  • Attempt to read property "foo" on null
  • Typed property Foo::$bar must not be accessed before initialization

These errors generally aren't too difficult to diagnose, but if another developer wrote the component, and particularly if the property is used in a less straightforward way (e.g. within an Alpine component), it can become much less obvious what is causing the error.

Also, there is no distinction between properties that need to be passed to the component, and properties that are simply set within the component itself (via actions etc.). So, again if another developer wrote the component, it's not always clear what needs to be passed via attributes unless it is documented.

Solution

This PR adds a simple #[Required] attribute that can be added to properties that should be passed to the component. If any required attributes are missing, an error will be thrown on mount:

Missing required properties [foo, bar] in component [my-component]

@francoism90
Copy link
Contributor

I don't fully understand this PR. Hopefully you can give an example. :)

class ChildComponent extends Components
{
	public Post $post; // throws error when not passed in parent
}

Do you mean without a typehint?

@oli-laban
Copy link
Author

I don't fully understand this PR. Hopefully you can give an example. :)

class ChildComponent extends Components
{
	public Post $post; // throws error when not passed in parent
}

Do you mean without a typehint?

Both with and without. A typed property as in your example doesn't throw an error, it's simply left undefined.

@lrljoe
Copy link
Contributor

lrljoe commented Jan 24, 2025

What's wrong with using Validate here? Seems a duplication.

I think you'd need to add in capability for "sometimes" etc if implementing, as that'll be an almost immediate ask

To be honest, I'd expect people to be using try/catch anyway

@oli-laban
Copy link
Author

@lrljoe

What's wrong with using Validate here? Seems a duplication.

Different use cases. This simply ensures that any required attributes are passed to the component on mount, whereas validation isn't run on mount.

You could get Validate to do the same thing by calling $this->validate() inside mount() but that adds weirdness if you want to validate any form data as well, and I wouldn't say it's a great solution regardless (you'd have to manually catch validation exceptions etc.).

I think you'd need to add in capability for "sometimes" etc if implementing, as that'll be an almost immediate ask

Not really sure how that's applicable here. If the attribute isn't present (in the same vein as a field not being present with regular validation), then that's the whole point of Required and an exception will be thrown. There's no further validation here because as long as your component properties are typed, then PHP will handle that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy