Search code examples
vue.jsvue-resourcevue-routervue-componentvuex

Method --> Action --> Mutation --> State issue


My function that's supposed to iteratively insert JSON into each element of a particular level of nested JSON using parameters from itself is duplicating the first object returned and inserting it into each nested parameter. See screenshots and code below to get a feel for what I'm doing.

Basically I have a nested JSON object within the state, and need to iteratively append to a nested property of each 'row' of the existing object using an action that returns JSON from an API then a mutation that updates the state.

The problem lies within the mutation I think. I've deduced my function is duplicating the first JSON object returned from the API. See Action and Mutation functions below, along with API function and structure of JSON.

http://api.capecodcommission.org/docs/index.html#sumofannualcapitaltotalsfortreatment

Function within a particular component run using v-for:

methods: {
    costTotal () {
      return this.updateFinTotals(this.treatment.treatmentId,this.costType.treatTotal,this.costType.financeOption,this.treatment.relativeStartYear,this.costType.finDur,this.costType.prinFor)
    }
  }

Running function, viewing JSON:

<td class="text-center">
    {{ costTotal  }}
    {{ costType.annualized.sumOfAnnualCapitalTotals }}
</td>

V-for Loop:

<tbody>
    <tr v-for="(index, costType) in treatment.costTypes | filterBy 'true' in 'financeable'" is="cost-type-table-row-finance" :cost-type="costType"></tr> 
</tbody>

API function:

getSumOfAnnualCapitalTotals (treatmentId, costToFinance, financeOption, relativeStartYear, financeDuration, principalForgivenessRate) {
    let data = {
      treatmentId: treatmentId,
      costToFinance: costToFinance,
      financeOption: financeOption,
      relativeStartYear: relativeStartYear,
      financeDuration: financeDuration,
      principalForgivenessRate: principalForgivenessRate
    } 

    return Vue.http.post(API_ROOT + 'sumOfAnnualCapitalTotalsForTreatment', data)
  }

Action: Pulls JSON from API, dispatches mutation function.

export const updateFinTotals = function ({ dispatch, state }, treatmentId, costToFinance, financeOption, relativeStartYear, financeDuration, principalForgivenessRate) {

  api.getSumOfAnnualCapitalTotals( treatmentId, costToFinance, financeOption, relativeStartYear, financeDuration, principalForgivenessRate ).then(function (response) {

    dispatch('UPDATE_ANNUALIZED', response.data)

  }, function (response) {

    console.log(response)
  })
}

Mutation: Updates state with JSON.

UPDATE_ANNUALIZED (state, annualized) {
    for (var i = 0; i < state.scenario.treatments.length; i++) {
      for (var j = 0; j < state.scenario.treatments[i].costTypes.length; j++) {
        state.scenario.treatments[i].costTypes[j]["annualized"] = annualized
      }
    }
  }

EDIT: PICS BELOW

Component: https://i.sstatic.net/TuNsZ.jpg

JSON Structure: https://i.sstatic.net/zzNwi.jpg


Solution

  • Well, your API returns one value (for one cost-type of one treatment)

    Example from linked API docs:

    {"sumOfAnnualCapitalTotals":150374.9849625}
    

    but you assign it to all cost-types of all treatments with the for loop in the mutation:

    for (var i = 0; i < state.scenario.treatments.length; i++) {
      for (var j = 0; j < state.scenario.treatments[i].costTypes.length; j++) {
        state.scenario.treatments[i].costTypes[j]["annualized"] = annualized
      }
    }
    

    what you should be doing is pass the treatmentID and cost type (which, I sherlock-holmed, is called costToFinance) from the action to the mutation, then filter the state for the matching object, and update only that:

    UPDATE_ANNUALIZED (state, treadmentId, costToFinance, annualized) {
    
      const treatment = state.treatments.find((t) => t.treatmentId === treatmentId)
    
      const currCostType = treatment.costTypes.find((costType) => costType.Id === costToFinance)
    
      currCostType.annualized = annualized
    }
    

    The problem is that your JSON doesn't seem to have any ID for the costTypes to find it by, but that's for you to figure out.