0

I am having trouble with a computed property within dynamically populated array of objects. I have an array of customers which are filled dynamically by the user in the form. The user can add as many customers as he likes. Each customer has a price field calculated based on some other values in the object. Additionally, the price for each customer is based on some generic settings that apply to all customers.

Therefore I have a computed function which should update the price for each customer. The function starts like this:

this.booking.customers.forEach(function(customer) {
    var price = 0;
    self.booking.packages.forEach(function(package) {
        ... // based on the packages the price variable is changing
    }
    customer.price = price;
}

The calculation works - because if I open the vue devtools the value is suddenly applied, and then Vue also recognizes the dependencies (as soon as I change some value all prices adapt accordingly).

So my problem is: initially, Vue doesn't update the property correctly. As soon as I open devtools once, from that moment on it adapts accordingly.

Maybe I am not using computed properties in the right way, but using a method is also not what I need because I want the price value to change as soon as any dependency is changing.

Hope the problem is understandable. Thanks in advance for your help.

EDIT:

Here is a fiddle which maybe highlights the problem better. I think I am misusing computed values, but I have no idea how to tell Vue that the prices need to change whenenver some other values change. http://jsfiddle.net/6bw50j9d/2/

ANOTHER EDIT: I was able to solve my problem using deep watchers, I found this solution in another post. See Vue.js - How to properly watch for nested properties

Matthias S
  • 3,358
  • 3
  • 21
  • 31
  • 1
    Do you mind sharing a bit more of the code, as in, showing clearly the component data, the computed properties involved and the methods. – 8bit Nov 04 '17 at 16:49
  • Yes. I'll edit my question. – Matthias S Nov 04 '17 at 16:55
  • Can't really figure out why the property is not updated correctly at first... when is the function called? Also it seems funky that when you turn on the dev tools that the code suddenly behaves correctly. Use the dev tools to run a debug cycle once, see what happens. Also you can use ES6 arrow functions as anonymous functions in the forEach so you don't need to assign this to self at the top there, as this will not be overridden. – 8bit Nov 04 '17 at 17:12
  • 1
    This looks like a [change detection caveat](https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats) issue where `customer.price` needs to be set using $set. But, this is also probably a mis-use of a computed property as well. Computed properties are intended to return values. – Bert Nov 04 '17 at 17:21
  • Could you have a look at this very small fiddle which highlights the problem and let me know how I need to change this to let the price actually change whenever a dependent value changes? http://jsfiddle.net/6bw50j9d/2/ – Matthias S Nov 04 '17 at 17:36
  • Is this more what you are looking for? http://jsfiddle.net/65ngf0hj/2/ – Bert Nov 04 '17 at 18:02
  • hard to understand what's the actual problem from the fiddle, or the big amount of text – LiranC Nov 04 '17 at 18:19
  • Thank you Bert, that also works for me. But it feels a bit like a workaround, since I am not modifying my existing object. While trying to figure it out I came across another Question - I solved the problem now using a deep watcher instead of a computed value: https://stackoverflow.com/questions/42133894/vue-js-how-to-properly-watch-for-nested-properties – Matthias S Nov 04 '17 at 18:26
  • My excuses for my bad communication, its been a long day: I was trying to change a nested objects property based on other properties within the same object. The computed function did not run properly (maybe it was not detecting the dependencies - you can see that the price is not changing in the jsfiddle although there is a computed function). – Matthias S Nov 04 '17 at 18:30
  • I think a watch is another good way to go about it. I could make the argument for the computed because it seems like the price is always a calculated value which means it doesn't make as much sense to make it a static property of the object, but I wouldn't argue too much over using a watch. – Bert Nov 04 '17 at 18:43
  • Feel free to formulate an answer I'll gladly accept it - it did solve my problem :-) – Matthias S Nov 05 '17 at 11:07

0 Answers0