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

Question: A user edit form initial state #47

Closed
patricknazar opened this issue Feb 14, 2018 · 5 comments
Closed

Question: A user edit form initial state #47

patricknazar opened this issue Feb 14, 2018 · 5 comments
Labels

Comments

@patricknazar
Copy link

Hi, just discovered this repo today and I like it. I am considering using it as it looks quite beneficial.

Just after a bit of guidance here. I would be creating a user edit form (after selecting a user from a list) and have the following questions about how I would do that here:

  1. How do I initialize the form state using user data? None of the examples seem to do this - probably something simple I'm just missing philosophically speaking. An initial action dispatched somewhere else perhaps?
  2. Do all users' edit forms share the same state key? i.e. something like selectedUser: User? That will need to be cleared/reset/updated when another user is selected.
  3. If the user's data were to change during editing - how to ensure a good user experience (i.e. not suddenly replace the values you're changing with the latest ones)
  4. If the form is updating selectedUser, wouldn't other components now display unsaved data? Seems wrong - as I would expect to update that state only after successfully updating the user. Need both a selectedUser and a selectedUserForm ?

Hopefully my questions are clear and that someone can help fill in my quirky knowledge gaps. Thanks

@jacqui932
Copy link

jacqui932 commented Feb 14, 2018

Just trying to 'pay it forward' as MrWolfZ has been very helpful to me.

  1. The method I have used for this is to create an action which fires on User selection, takes the current User object and then initialises the form from it - something like this:
export enum Types {
  SELECT_USER = 'SELECT_USER'
}

export class SelectUser implements Action {
  public readonly type = Types.SELECT_USER

  constructor(public user: User) {
  }
}

const USER_FORM = 'USER_FORM';
export function reducer(state = {entryForm: INITIAL_STATE}, action: userActions.Actions): State {
    switch (action.type) {
        case userActions.Types.SELECT_USER:
            const newState = createFormGroupState<UserValue>(USER_FORM_ID, {
               name: action.user.name
               ......
           }
            return newState
    ....
}
  1. You shouldn't need extra state as the user is only used for initialising the form as above.
  2. Not sure in which way the data could change?
  3. Again, shouldn't need the user to be stored anywhere - just used for initialising the form.

@patricknazar
Copy link
Author

Thanks for the reply. Seems reasonable. With 3, it would be a real-time update from a websocket or something that would update the user in question in the list of users state. As soon as this happens, the content in the form is out of date. I figured being a reactive store there might be a commonly used pattern in this situation. The situation that comes to mind is if the user has several addresses, ie an array, someone else editing the user at the same time could completely rewrite a painfully entered bunch of addresses. Thoughts? Is is a separate backend related issue?

But yeah most of that makes sense to me. I'll give it a go, cheers

@MrWolfZ
Copy link
Owner

MrWolfZ commented Feb 14, 2018 via email

@MrWolfZ
Copy link
Owner

MrWolfZ commented Feb 14, 2018

Alright, finally found some time. For most of the questions the answer is "it depends". Since I don't know your exact use case its difficult to provide concrete others. Therefore, I'll try to provide you with options and point out some of the trade-offs.

  1. @jacqui932 posted a good example. You can see the full example I provided him with here. It contains similar initialization logic as you ask for. I might take this up in the user guide or maybe an FAQ.
  2. It all depends on how you want to structure the code. It is perfectly valid to have only a single form state that gets re-initialized any time the selected user changes. However, I would recommend having a separate form state for each user and then dynamically set the correct form state to the HTML elements based on the selection. The advantage of the latter approach is that changes are made to one user without saving the form state will get persisted through selected user changes, e.g. if the name field was edited and then the selected user was changed and then changed back again the edited value is still in the form. If this is not desired I would go with the former approach.
  3. Each form control tracks whether its value has been changed through the isDirty property. In my applications when I need to update a form state with new data I simply check if the state is dirty and if so don't update that specific state. In addition, for some use cases you may want to inform the user that the data was updated. Say you have case where two people might be editing the same entity at the same time. If one of them saves and the other gets the updated data you could show a message, e.g. "The user you are editing has been changed by someone else" and show them the current value to let them choose whether they want to keep their changes or override them. This approach is of course a bit more complicated but easily doable by simply checking for the isDirty property to figure out if the same data was edited already.
  4. Yes, in my applications I always try to separate my business or domain model from the form state. That means I keep the data redundant and only synchronize it at specific times (e.g. the user hits the "Save" button, focuses another form field, some time expires, etc.). Therefore I recommend that you do not re-use the form state in other parts of the application. However, your specific use case might require just this and in that case there is nothing that stops you from doing this.

I hope this answers your questions.

@patricknazar
Copy link
Author

Really appreciate the time you've taken to help me here. Has really helped! Thanks so much

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

No branches or pull requests

3 participants