Skip to content

[RFC] Handling Data with Bad Types (i.e. that fails hydration) #528

@weaverryan

Description

@weaverryan

Hi!

Consider this component:

#[AsLiveComponent('counter')]
final class CounterComponent
{
    #[LiveProp(writable: true)]
    public int $count = 0;
}

In the template, it's bound to an input:

<input data-model="count">

What should happen if I enter apple into that box? (Note, yes we could use <input type="number">, but there are other examples , like a DateTime property where an invalid date time string is passed).

I can only think of two options:

A) We advise to NOT use property-types for writeable properties. The idea is that the component represents the "client-side data". And so if you can type apple into a field, then we should allow for apple to be entered on the property. Then, you use #[Assert\....] validation to validate things.

B) If there is a type mismatch, we reject the new value then, somewhere, expose an "error" that the user can render (e.g. errors.get('count') would have a message).

(B) is attractive, but tricky. It would require:

  1. On the Ajax call, in addition to the "latest data" (e.g. the latest count value), we would also need to send all of the "original data". This is needed because, if count was previously 10 and the user types in apple, we need to know the original value (10) so we can set it onto the property (since we will not be setting the string apple). If we didn't do this, the invalid property would go back to its original default value (if it has one, e.g. 0, which would look weird) or, worse, it would remain "uninitialized" and result in an error.

  2. On the frontend, we would need to be smart enough to realize that if we send a value of apple for count, when that Ajax call finishes, because count was invalid, that data is still in an "unsynchronized" state. This means that the the <input field should not be updated to hold the latest value from the server (which would be the original 10 at this point).

So, solution (B) is doable. But we should be sure that it's not overkill - i.e. that solution (A) doesn't work well enough or something else.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions