Is App Connect two way data binding?

I’m using a Data Detail component to display record detail and one of the fields is an array of objects, or child records for the parent. I’m displaying them on a form that the user can interact with. When the user changes a value in one of the inputs, does the underlying object or value (in the Data Detail) get updated?

I have a sum of two values from the Data Detail child records (Quantity*Price) but when I change the quantity or price, the sum is not updated and I’m wondering how to get it to work.

The data detail gets its information from the server connect and is read only.

The change in price, quantity and resulting changed sum, should be submitted to an update action on the server. On success, the server connect should be loaded and the data detail will show the change.

This brings me to ask you (as I understand it) why you have an array of objects in your database table. Should you not have a related table with the objects?

image

I don’t have the array of objects in the table, that’s just the way I have the server connect configured to send them to the client. My setup is pretty much like yours, it just sends the details as an array of objects for each parent record. I then am displaying the results in a repeat on the form and allowing the user to interact with the data.

As you can see, the calculations all work for a saved record. My problem is when the user goes to add a new row or change an existing row, the calculations don’t update.

Here I just changed the quantity, and the Amount and Total remain unchanged:

I have to save the record and reopen it to see the correct calculations. Is there any way to make it “live”?

It depends on how do you do your calculations. Are you using the values from the database or the values of the inputs to make the calculations?

If you are using the database values for your calculations, changing an input value won’t change anything.

I have a Server Connect that returns the data from the database and a Data Detail that is connected to the SC, configured to show the selected record. One of the fields in the Data Detail is the OrderDetails array:
image

I also have an Array component that gets it’s items from this OrderDetails array and the repeat is bound to the Array:
dmx-bind:repeat="arrOrderDetails.items"

I had originally used the OrderDetails array directly from the Data Detail, and that worked, but I couldn’t figure out how to add new entries (different subject) so went with the Array component.

The inputs in the repeat are bound to the array like: dmx-bind:value="Quantity"

And, my calculations are referencing the Array component: arrOrderDetails.items[$index].UnitPrice*arrOrderDetails.items[$index].Quantity

My hope was that when a value in one of the inputs changes, the array would get updated and the calculations would reflect that change, all the way to the total at the bottom. That’s the way Angular works and I am trying to get that functionality.

I am a little confused by what you are doing exactly.
Just to clarify - if you are using the input values in your formula it will update the result when the input value changes.
If you are not using the input values in the formula, then you need to update the values you are changing…

It should be one in the same, if it was bound both ways. If the input is bound to the array, when the input changes, the array is updated and any reference to the array will reflect that change. That would make my total at the bottom work as well. I can change the Amount calculations to reference the inputs, but that doesn’t take care of the Total at the bottom. How do I get a total of all rows?

Currently my calculation is: dmx-text="arrOrderDetails.items.sum(UnitPrice*Quantity).formatCurrency('$', '.', ',', 2)"

Well have you bound it both way? Do you uplade the array on change?
I think you expect this whole thing to work in a way different than it actually works.

Can't really answer this question directly as I only see a couple of lines from your code and have no idea what are you doing on the page.

I’m just trying to get the total for each row and then the total of all rows at the bottom.

In Angular, if I bind an input to a variable, whenever that variable changes, the control changes and whenever the control changes the variable changes. By the above statement about App Connect being just as powerful as these other frameworks, I was expecting similar functionality. Maybe it’s not that way.

If you use a variable as a dynamic value for the input, the input just displays the variable value, it does not update it.

So you need to update the value back if you want it to update and use it in some calculations.

Well, that’s disappointing. Thought maybe I was doing something wrong that it didn’t work…

I have the Amount referencing the inputs and that’s working now. So, without updating the array, how would I get the total of all rows in the repeat? Is there some way to dynamically reference each input? There could be one or many rows in the repeat.

BTW: you can go to: https://cam-testing.azurewebsites.net/orders and click any row to edit, then click the Products tab. Change any row’s price or quantity to see the Amount change. I want the Total at the bottom to reflect those changes as the price and amount change.

Have you tried summing the input values, like:

{{tableRepeat_OrderDetails.items.sum(`inp_Amount.value`)}}

It won’t work with inp_Amount as it is not a numeric value, but just add a hidden field like the other inputs and use its value instead.

Oh, I didn’t know items was available in the repeat like that. Thank you! That works great.

To get it back to a numeric value, I’m using this expression:

{{tableRepeat_OrderDetails.items.sum(`inp_Amount.value.replace('$','').replace(',','').toNumber()`).formatCurrency('$', '.', ',', 2)}}

So, theoretically I don’t need the Array component any more, except that I need to be able to add new rows and that was the only way I could figure out how to do it. I’m wondering if there is a way to add them directly to the repeat? Is there an add method or equivalent on that object? If there was, I could base the repeat on the Data Detail component and eliminate the Array.

Also, one little detail I’m trying to work through is for deleting rows that are already in the database. The concept is that those rows will have an OrderID value and the delete button inserts a ‘D’ in front of that value and the server connect deletes those from the database when it sees that D. But the calculation will have to filter those out in the total. The UI has: dmx-hide="inp_OrderID.value.substr(0,1) == 'D'" so deleted rows are hidden.

To handle those, I changed the Total calculation to:

{{tableRepeat_OrderDetails.items.sum(`(inp_OrderID.value.substr(0,1) != 'D' ? inp_Amount.value.replace('$','').replace(',','').toNumber() : 0)`).formatCurrency('$', '.', ',', 2)}}

And that seems to work, but is that the right way to go about it? Or is there a better way to ‘filter’ out certain values?