Search code examples
vue.jsv-for

change object value v-for inside v-for in vue.js


I am quite new in vue. I have 2 array data like this :

listAccount : [
    {
        id_acc : a,
        amount : 1000
    },
    {
        id_acc : b,
        amount : 2000
    },
    {
        id_acc : c,
        amount : 1000
    }
]

listTransaction : [
    {
        id_acc : a,
        type : inc,
        amount : 100
    },
    {
        id_acc : b,
        type : inc,
        amount : 100
    },
    {
        id_acc : a,
        type : dec,
        amount : 100
    },
    {
        id_acc : a,
        type : dec,
        amount : 100
    }
]

and this is my component code

<div v-for="(list,index) in listAccount" :key="index">
    <div> {{list.id_acc}} -- {{list.amount}} </div>
    <div> transaction :</div>
    <div v-for="(each, index) in listTransaction" :key="index">
        <div v-if="each.id_acc == list.id_acc">
            <div> {{list.type == inc ? list.amount + each.amount : list.amount - each.amount}} </div>
        </div>
    </div>
</div>

i got result like this

my result:
a -- 1000
transaction:
    1100
    900
    900

b -- 2000
transaction:
    2100

c -- 1000
transaction:

but i want my result if the transaction type "inc", the transaction amount increase the amount of my account and if transaction type "dec", the transaction amount decrease the amount of my account if the transaction have same id_acc. my expected result like this:

expected result :

a -- 1000
transaction:
    1100
    1000
    900

b -- 2000
transaction:
    2100

c -- 1000
transaction:

i don't know how to change parent element value. can someone help me?


Solution

  • As mentioned in the comment, make a computed prop with all that you need then simply output it in the view, rather than calculating things on the fly inside the view.

    Slightly diff to your expected output but with more details so you get the idea.

    //
    new Vue({
      el: '#app',
      data: () => ({
        listAccount: [{
            id_acc: 'a',
            amount: 1000
          },
          {
            id_acc: 'b',
            amount: 2000
          },
          {
            id_acc: 'c',
            amount: 1000
          }
        ],
        listTransaction: [{
            id_acc: 'a',
            type: 'inc',
            amount: 100
          },
          {
            id_acc: 'b',
            type: 'inc',
            amount: 100
          },
          {
            id_acc: 'a',
            type: 'dec',
            amount: 100
          },
          {
            id_acc: 'a',
            type: 'dec',
            amount: 100
          }
        ]
      }),
      computed: {
        accountTransactions: function() {
          for (let account of this.listAccount) {
            account.startingBalance = account.amount
            account.transactions = this.listTransaction.filter(i => i.id_acc === account.id_acc)
            account.transactions.map(i => {
              i.beforeBalance = account.amount
              account.amount = i.type === 'inc' ? (account.amount + i.amount) : (account.amount - i.amount)
              i.afterBalance = account.amount
            })
          }
          return this.listAccount
        }
      }
    });
    .transactions {
      margin-bottom: 20px
    }
    <div id="app">
      <div v-for="(account, index) in accountTransactions" :key="index" class="transactions">
        <div>
          {{ account.id_acc }} -- Starting Balance: {{ account.startingBalance }} End Balance: {{ account.amount }}
        </div>
        <div> transactions :</div>
        <div v-for="(transaction, index) in account.transactions" :key="index">
          {{ transaction.beforeBalance }}: {{ transaction.type }} {{ transaction.amount }} = {{ transaction.afterBalance }}
        </div>
      </div>
      
      <strong>Structure of computed prop</strong>
      <pre>{{ accountTransactions }}</pre>
    </div>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.14/vue.min.js"></script>