6

Calling in all Vue devs here! (Possibly any SPA dev actually)

We're building these fancy live-edit fields for our app. It syncs with the database with every keypress (with a debounce, ofc). Now, we're having a global Vuex module to keep track of the applications sync state. Using this module, we can prevent the user from leaving the page if there is data that hasn't been synced. Though, I think I'm doing something wrong here, and not strictly adhering to the "single source of truth"-principle.

When a user has finished typing, a request is made through Axios. When the response arrives, the field issuing the request updates it's display accoring to the response. However, there is also an Axios interceptor which updates the global state to reflect the latest response. Is this wrong? Should the fields themselves emit the mutation to the store? Or is it okay to use an interceptor since they're running down the same call stack?

I think my biggest worry here is that the interceptor and the field will interpret the response differently...

Help is appreciated :D (and thanks for taking the time)

Comments
  • 6
    Syncing with database on every keypress? Wouldn’t that make thousands of call in seconds with huge user?
  • 2
    @devTea We're debouncing the input. Haven't settled on a specific value yet, but probably somewhere between 500-1000ms
  • 3
    @ScriptCoded what’s wrong with updating the database on form submit?
  • 1
    @devTea Well, technically, no, but from a user perspective it's pretty neat. It's especially nice since there'll be a lot of editing going on.
  • 4
    @ScriptCoded normal user probably don’t understand that anyway, and unless the connection is on local, there’s probably going to be a problem ahead
  • 3
    Personally id rather have a submit button, because if i make a mistake and want to undo it that is goi g to have problems if it is auto saving, especially if it has a lot of input fields and requirements
  • 1
    @devTea Well, it's pretty standard nowadays if you look at growing platforms/websites. Any specific problems you see?
  • 4
    @ScriptCoded pretty sure updating database on every keypress is not standard, did you mean updating state?
  • 3
    I don't know your circumstances so this is just my initial reaction, but I agree it doesn't sit well with me how the fields and vuex will seemingly sit on unrelated data. It seems more intuitive to me if the fields were reading from vuex instead.

    I digress, but I realized the other day that you can hook up props directly to the store state. Saved me some pointless computed variables by just going :title="$store.user.state.username"
  • 1
    @devTea Yes, the state is updated on every keypress, but the database update is on a debounce. There has to be some idle before issuing a sync.
  • 1
    @ltlian Yeah, that's what I thought aswell... The thing that bugs me is that in that case the store would have to store every single input. On top of that if would have to reset on every page navigation. Isn't that a bit too much?
  • 1
    @RicoNijeboer Some forms will have submit buttons, such as for creating things. But yeah, perhaps resetting is something that's good to have.
  • 2
    @ScriptCoded "Storing every input" in terms of "commits" to the vuex store, you mean? I don't believe that's a concern in terms of performance. As far as I know you are still just passing references to variables and not actually copying and allocating things like in a database.

    I have a table which updates every second or so by taking a ~50kb json from the store, which it gets from a socket connection that writes to it. I've never had any performance issues with it and it behaves better than when I had a bunch of jank doing it via computed variables and watchers.
  • 2
    @ltlian Perhaps I'm getting you wrong, but performance isn't the issue here. Though good to know it won't be either ;)

    I'm wondering if:
    A. The inputs should depend on the store, which in turn depends on the request result
    B. Both the inputs and the store should depend on the request result.
    Or C: The inputs should depend on the request result, and in turn commit to the store.

    In this case everything that's kept in the store is the status of the sync (saved, syncing, error).
  • 1
    @ScriptCoded

    A - the problem here will be latency. The user would probably perceive the input lag as it'd be greater than 40ms.

    B - More than one source of truth issue. It's fine if the local store is used as a local backup in case of missing data though, but the input content would have a greater priority (unless the store content is newer e.g. in a page reload).

    C - Once again the problem of perceived latency. IMO the input content should not depend on network requests.

    In conclusion, I think B is manageable, you just need to solve data discrepancy scenarios by establishing a priority based on the most recent edit (maintaining one source of truth).
  • 3
    If you have a submit button, but also send and store all input on keypress... the software is behaving differently than presented. You're lying to the user.

    Someone could fill out your form, decide not to submit, and close their browser instead. But you've already captured their info.

    That is terrible and you should be ashamed.

    Hell. Facebook does this shit and even analyzes what you typed but didn't post.
  • 3
    @Root 😈

    I agree, a submit button is misleading.
  • 1
    @ScriptCoded B is ambiguous.
    Your input should depend on your store and your store only.
    The request will, in case of a failure, invalidate the state which will in turn rollback the input value.
    (hence single point of truth)

    Note that this behavior is quite bad and you absolutely can and should implement a retry.
Add Comment