Show live changes depending on nested data
I have an
Invoice resource that has_many InvoiceItems. Every InvoiceItem gets some data (quantity, tax_rate, unit_price) and calculates the item's total amounts in a change.
In the Invoice-create_invoice action I want to aggregate all the taxes, this means iterating all items and building sums. The way I currently do this is by running the action and then updating the invoice in an after_action hook, as I could not find a way to access the InvoiceItem's data before.
This works fine, the problem is that it breaks live updating forms – I'd like to show the calculated amounts immediately using the after_action hook breaks this. Is there a way to work around this?
I think I need a way to run the nested items' changes first or at least make sure the inputs to my nested resource are valid, in this case I could calculate the value in the Invoice's changeset. I feel like there must be a way to do this, I just could not figure it out yet 🙂Solution:Jump to solution
I couldn't really find out how to use
transform_params here. As far as I can understand it's helpful for updating the parameters that get passed to the form, but my "calculated" fields are not actually part of the form.
I was able to figure out another way – maybe it's helpful for someone else, so I'll share it. The solution was quite easy:
1) Run the necessary calculations in the top level changeset (also):...3 Replies
I think for a lot of these complex UI stuff currently folks are just doing it in the UI
using things like
transform_params and Ash.calculate etc.I see. Could this be improved in the future? I think it would be nice and follow the Ash paradigm if this could be handled in one place
Solution
I couldn't really find out how to use
transform_params here. As far as I can understand it's helpful for updating the parameters that get passed to the form, but my "calculated" fields are not actually part of the form.
I was able to figure out another way – maybe it's helpful for someone else, so I'll share it. The solution was quite easy:
1) Run the necessary calculations in the top level changeset (also):
From this
to this
The "trick" here is not to wait for the actual results but calculate them using the children's changeset.
2) Use @form.source.attributes in the LiveView to get the updated values: