VUE 3 JS Save value if object changes - vue.js

I'm new to VUE but not to programming. The project is to convert an older server-built website to VUE and I'm looking to find the most efficient method to save data.
When a form (page) is loaded I pull the data from our server in a JSON object which is nicely converted to a JS object. Its big -- hundred or so properties.
I'm currently storing the object in a PINIA store as a reactive object, applying the object values directly to form inputs using v-model and everything works, is reactive, and once completed my object has all the necessary information to update (patch) the document.
What I'd like to do is send to the server JUSt the object that was changed and its new value.
For example: assume the object has many fields -- I'll just provide a few here
event:{user:'scott',pass:'12345',startDate:'11/01/2023',endDate:'11/01/2024'.....}
The page has tabs and in each tab we pull a subset of the complete object (fetched and stored).
Therefore, store.event object has one change -- startDate --
I'd like to build a function that watches the entire (100+ object), fire if any field has changed, then save it somewhere without an individual watch or computed property for each 100+ objects.
Suggestions?
I tried using watch with multiple elements -- it did fire but I was unable to determine which element (object) changed.
Watch(() => [store.event.contractdate,store.event.contractduedate],(cv,ov){.. do something}

Related

VueJS - Update a parent computed property after a child component modifies prop data

I have a relatively complex API request object I need to make, with a large number of UI components responsible for updating different properties of the object.
I'm passing the basic request model as a prop from a parent component to its children, which pass it on to theirs (down several "generations").
At the parent level, I have a computed property that returns a field of this data model, and a watch on that computed property.
When a child component updates the property on the model, it successfully updates everywhere that has a reference to it, but the computed property on the parent fails to recalculate, and resultantly the watch never activates.
I'm guessing I've missed the point somewhere along here, but I can't think about how else to update without resorting to long event chains through the UI.. How should I be approaching this instead?
To anyone with a similar question - from my research it seems that modifying reference values on props is not the intended approach for VueJS. Which is a shame, because initially it seemed like quite a neat pattern.
I've implemented vuex now, which is working well, and avoids long lines of events going back to the original owner of the prop data.
IF you wanted to press it, then modifying references on the object itself will force updates down the chain. So (e.g.) if you wanted to update an array property of the prop data, then instead of "pushing" to it, you would replace the whole array object (causing other components with computed properties on that array property to recalculate). But again, not recommended.

Vue watcher restore old values?

im using this component to make a list of sortable items.
https://sortablejs.github.io/Vue.Draggable/#/simple
I have one array with the items in my view component data.
Then i use an v-for to pain the list, one row for each item in my array.
So everytime i move one item, the array of items gets sorted and change the order of the array items, thats the behaviour of this component.
But i have to make a post call to an api to save the new order fot the list.
So i defined a watcher over the array of items, and everytime it gets sorted by the draggable component, i make the request to the api if the array order has changed.
The problem comes when this request fails, i want to restore the old values in the view, so i dont have one order in the view an another different stored in database.
Inside my watcher i have prevValues and newValues, that i use to compare and check if there is any change in the items order, then make the request, and then, if the request fails, restore the datavalue with the prevValues array.
The problem is that could get to an infinite loop, because when i restore the old values, the watcher over the original array is triggered again, make the request, fails, restore values and so on.
Is there any way to restore old values passed to a watcher without triggering the watcher again?
Thank you
It would be more reliable to react to drag events to trigger your API calls, rather than watching the data. That way your code only does work in response to user action.
Alternatively, stash a copy of the original array and use something like deep-equal to compare it to the latest value to determine if changed before making a call.

Is it a good idea to pass whole object to child component?

It's a question about performance
I have a big object with a huge amount of fields (and maybe with a nested objects too).
I have a page component, it receives this object from server.
I have some child-components inside page component. One component needs a several fields from the object, should i pass them as a single prop for every field, or i can pass a whole object? Is it affects to performance?

el-select not showing selected label when v-model is manipulated in beforeMount()

el-select is not displaying the label of the selected option but is correctly updating the v-model with el-option :value. It is probably due to the manipulation in beforeMount() as when that is removed, the label correctly displays the option selected.
However, multiple object copies are required for my use case which is to map headers from uploaded files to expected headers where each file can have the same expected header.
Here's a fiddle with my issue: https://jsfiddle.net/c8auL7fk/
I submitted a bug report for this here: https://github.com/ElemeFE/element/issues/13373 and a contributor got back to me.
Vue is unable to catch changes to dynamically created properties. Objects need to be written in an immutable manner.
More details on immutable js objects here: https://wecodetheweb.com/2016/02/12/immutable-javascript-using-es6-and-beyond/

Reacting to changes within observed object's unobserved properties

I have an external library with TypeScript class instances in observed variable of my app's store:
class Store:
#observable active_obj:ExternalClass;
This instance has a method which, when called, updates its internal state leaving the object as is:
store.active_obj.change()
Now, since Mobx is not observing this object itself nor its (I assume) properties, only changes happening directly on the field active_obj (like new value assigned to it). Since instances of MyClass are provided by external library and ultimately get rendered inside this library's components I can't add observables and observers to its class structure nor React components. Mind you, this is only what I think is the reason that changing the object's properties doesn't trigger re-render...
I had to cheat a bit by using other, observed variable I change directly with nonsense data at the same time I'm calling to unobserved instance for change. Adding references to this variable on components higher up the tree, I can trigger re-render that produces updates on the (unobserving) components of the external library.
My question is, how best to make Mobx aware of change so it can notify observers of store.active_obj instance?
I think this part of Mobx documentation warns about this, but there's no workarounds or solutions for it:
** If likes where objects instead of strings, and if they were rendered by their own Like component, the Likes component would not rerender for changes happening inside a specific like.
from here, at end of the page
Edit
As per #mweststrate's question, I provide some context:
My app controls its data, but it has to create external class' instances from that
Instance's data is encapsulated and mutated in place, but it's done by asking from my app's side through user triggered events (meaning, I know when data is updated)
Basically class uses app's data to provide different views into data based on user selection and renders it with its React components
I also use this changed data elsewhere in the app in components I control
Changed data is part of external class' internals and I can't depend on it
Since Mobx tracks mutations it can see, using Observable doesn't directly work
Some possible solutions I thought:
manually notify observers that observable active_object has changed when I have called the instance it references to change
have a container object that Mobx can track and when I change its sentinel property, that update is noticed and actual instance with it