-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Property fields of type Option<T> are not mandatory #3395
Comments
...if this is confirmed as a bug and somebody points me in the right direction, I'd be happy to contribute with a PR |
I feel the current behaviour is more desirable than requiring user to write a prop when the prop is Currently a
Requiring a prop to present only takes away 1 but not 2, that does not sound right to me. It is not possible to take away both 1 and 2 based on whether I think this is also consistent with the behaviour of HTML Elements, where omitted attributes are treated as However, I do agree that the documentation should be adjusted to reflect this behaviour. |
thanks. Regarding forcing users, whoever develops de component is responsible for making it convenient or not to the component users. There is already a way to "use default if not provided"; prop_or_default. If I search for code containing #[prop_or_default] with fields being Option, I get several results: https://github.com/search?q=repo%3Ayewstack%2Fyew%20%23%5Bprop_or_default%5D&type=code (I also found occurrences in my code) all in all, I'd suggest we treat all types of fields the same as there already is a documented (and used) way of "using default if not provided". |
... and after re-reading your message again I think I see what you meant about option 2 doing the "val -> Some(val)" conversion behind the scenes. |
in case this is of any value, I was curious to find out why was I using #[prop_or_default] in for Options so I tested with yew 0.20, 0.19, 0.18 and 0.17. On 0.17 this was failing at compile time: error[E0599]: no method named `build` found for struct `app::PropsBuilder<app::PropsBuilderStep_missing_required_prop_mandatory>` in the current scope
--> src/app.rs:49:9
|
3 | #[derive(Properties, PartialEq, Clone)]
| ---------- method `build` not found for this struct
...
49 | / html! {
50 | | <Child />
51 | | }
| | ^
| |_________|
| method not found in `PropsBuilder<PropsBuilderStep_missing_required_prop_mandatory>`
|
= note: the method was found for
- `app::PropsBuilder<app::PropsBuilderStep_build>`
= note: this error originates in the macro `proc_macro_call_0` which comes from the expansion of the macro `html` (in Nightly builds, run with -Z macro-backtrace for more info)
|
@futursolo I noticed a
It sounds right to us though. This is simply about not providing the prop at all. If an equivalent syntactic
This is not a good argument. That is JS, this is Rust. |
I removed the bug label because this behaviour is intentionally introduced, although the documentation didn't reflect this special behaviour for This issue is proposing a behaviour different than what this macro is currently trying to do.
I do not think these solutions are better than writing
This behaviour can also be observed in Rust.
Since there is no compile stage in ordinary JavaScript, you cannot complain about JavaScript does not give you compile time errors. JavaScript is horrible in many ways, but this is not one of them.
I think this behaviour is consistent with HTML Elements, if you want an attribute to be set, then it is present, if you want it to be null-ish, then do not have it present. You never pass an explicit value to an attribute to represent a null / None / nil-ish value. If I have to say, I would argue explicit passing |
If/when I develop a component who's property field is If/when I develop a component who's property field is I think we're really mixing passing None with not passing something, and this may be ok in some scenarios but I don't think the framework should be opinionated here (and it already provides prop_or_default in case I want to bypass the 'all fields are mandatory' rule). all in all, it does look like a special/arbitrary case when the possibility of transform behavior (prop_or_default) is already there. The "magic" converting |
You have to. Missing
Attributes, attributes, attributes. I said that props are not attributes. An equivalent for attributes would be a
I don't think I mentioned compile-time? I said it was about types, and types are more-or-less checked in JS at runtime. I did in fact use |
I agree this is a surprising behavior. I don't remember why this change was made but if you can maintain all the current functionality and also make passing None a requirement, unless specified otherwise, I'd be happy to accept such PRs. @futursolo what do you think of that? I don't see how implicitly assigning None is a benefit when it can be explicit or the component author can opt into making it implicit. I think making the fact that None is passed to a property explicit and clear to the user is a good thing. |
thanks. I'll give it a try; if anybody is already doing this or has some hints on where to look at please let me know to avoid reinventing the wheel. |
yew/packages/yew-macro/src/derive_props/field.rs Lines 19 to 20 in 73f4bb9
|
As far as I remember, Yew doesn't guarantee backwards compatibility until version 1.0, so we could just get rid of the special case, or we can add a |
@schvv31n I'm certain that adding The whole Rust language is built upon making strict limitations to ensure bug-free experience, and only then opening it up bit by bit once the unrestricting logic can be figured out - see Non-Lexical Lifetimes. This If you get rid of special case, try ensuring that |
while #[required] might help my specific use case (property fields of type Option be mandatory), I think it's adding a corner case of a corner case. Unless there is a technical reason for this, I'd stick to the existing prop_or_* annotations. Comparing:
I'd say option 1 is clear, elegant, concise. Good. option 2 sounds like a clumsy workarround. |
Problem
I want to use Option as a property field.
I want to enforce users of my component provide me with that property always, which can be None or Some(something) but must be populated.
According to https://yew.rs/docs/concepts/function-components/properties#derive-macro-field-attributes:
Steps To Reproduce
Steps to reproduce the behavior:
Expected behavior
Since all fields are mandatory and I'm not passing the
mandatory
field of property, I expect this code to not compile.I suggest either the behaviour is changed so Option is also mandatory (as stated in the docs). People not needing this can always use #[prop_or_default]. Otherwise at least update the docs to reflect this special case for Option fields
Environment:
Questionnaire
The text was updated successfully, but these errors were encountered: