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

Vue error when domDelay is set to true, when modifying array. #19

Open
BinarySpike opened this issue Nov 15, 2018 · 3 comments
Open

Vue error when domDelay is set to true, when modifying array. #19

BinarySpike opened this issue Nov 15, 2018 · 3 comments

Comments

@BinarySpike
Copy link

When using ObservableSlim on a Vue.js data model, I'm running into a vue error when domDelay is enabled & you don't make changes right away.

See this gist for a series of tests: https://gist.github.com/BinarySpike/aa4f82fd024265b72fcde1327c7b0f09

Ultimately I got it working (test7), but it seems ObservableSlim is doing something that Vue doesn't like (test5), even when I've called pauseChanges and don't mutate the object myself (test6).

Below are the three issues I ran into.

  1. ObservableSlim does not respect Vue's reactivity.

pauseChanges and then use Vue.set in the observable (this is the recommended vue way)

  1. Changing a variable to a complex type and then trying to resolve prototypes on it such as Array and Array.push will fail in the same operation/batch

Disabling domDelay fixes this

  1. Some time after the an ObservableSlim is created on a VueJS model, using Array.push will generate a vue error.

Disabling domDelay fixes this, but it's not intuitive why.

My troubleshooting and intuition leads me to believe Vue is queuing/batching changes like ObservableSlim. Directly after creating the ObservableSlim, if you make changes, they are performed before Vue "wires-up." However, once Vue completes it's initial operations something is funky. It has something to do with the way ObservableSlim resolves/calls Array.push because direct access (test8) works fine.

I think test7 will work for my immediate needs, but I would like to know if there are solutions to problems 2 and 3.

@ElliotNB
Copy link
Owner

ElliotNB commented Nov 15, 2018

Thank you for the clean re-pro examples! I'll dive into this issue either tomorrow or this weekend and see what I can figure out. Off the top of my head, it sounds to me like Vue might be making additional mutations to the target object after the initial mutation. When domDelay is set to false, then your handler function is invoked before Vue has the opportunity to make any additional mutations.

In general, I'd expect that Vue models won't play very nice with ObservableSlim -- especially Arrays. In order to observe mutations on plain objects, Vue 2 uses Object.defineProperty -- but for arrays Vue wraps all of the mutation methods on the Array object: https://vuejs.org/v2/guide/list.html#Array-Change-Detection -- Wrapping all of the mutation methods on an Array could cause some pretty strange behavior when used in conjunction with ObservableSlim's Proxy-based observer. ObservableSlim works best when observing plain objects or plain Arrays (with any degree of nesting) -- not so much when observing a complicated model built by Vue that is observing changes via defineProperty and wrapping Array mutation methods.

Vue 3 will ship with a Proxy-based observer ( https://medium.com/the-vue-point/plans-for-the-next-iteration-of-vue-js-777ffea6fabf ) which might resolve the issues you've encountered.

@BinarySpike
Copy link
Author

BinarySpike commented Nov 15, 2018

Elliot, you made me realize I probably don't need to Observe my vue model directly. I can use a separate simple data model and directly modify the vue model from my handler. As long as both models have a matching initial starting value, they should transform the same.

Really loving ObservableSlim so far!

Edit
Been trying to solve how to bundle all my code as a nodejs module vs a browser include and saw this solution in ObservableSlim.js:
try { module.exports = ObservableSlim; } catch (err) {};

@ElliotNB
Copy link
Owner

Glad to hear that you were able to find a workaround! I haven't had a chance to dive deep into this issue yet, but it's still on my to-do list.

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

No branches or pull requests

2 participants