Home > Software engineering >  Undefined object fields in javascript reducer function
Undefined object fields in javascript reducer function

Time:08-26

I'm learning spread operators, reducer functions, and some general data manipulation. Thanks to some help here on SO, I have a working function that reduces my data objects to show the most recent assessments by date, with ID. That works great. I've added two more fields to the assessment objects (cadence and assessmentName) but I'm getting undefined for those fields in the result. Where am I going wrong?

Here's a stackblitz: https://stackblitz.com/edit/js-kzffrx?file=index.js

const result = data.map(({assessments, ...rest}) => ({
  ...rest,
  'assessments' : Object.entries(assessments
    .reduce((a, [{ id, date }]) => {
      a[id] = (a[id] || '').localeCompare(date) > 0 ? a[id] : date
      return a
    }, {}))
    .map(([id, date, cadence, assessmentName]) => ([{ id, date, cadence, assessmentName }]))
}))

console.log(result)
<script>
const data = [
  {
    "partnerId": "p0001",
    "partnerName": "Foo",
    "assessments": [
        [ { "id": "a0016", "date": "2021-03-20", "cadence": "Annual", "assessmentName": "FFIEC CAT Survey" } ],
        [ { "id": "a0016", "date": "2021-11-19", "cadence": "Annual", "assessmentName": "FFIEC CAT Survey"  } ],
        [ { "id": "a0011", "date": "2022-05-19", "cadence": "Annual", "assessmentName": "FCC Risk Assessment"  } ],
        [ { "id": "a0011", "date": "2020-10-29", "cadence": "Annual", "assessmentName": "FCC Risk Assessment"  } ],
        [ { "id": "a0001", "date": "2021-11-30", "cadence": "Semi-Annual", "assessmentName": "Counterparty & Financial Risk Assessments"  } ],
        [ { "id": "a0001", "date": "2022-06-07", "cadence": "Semi-Annual", "assessmentName": "Counterparty & Financial Risk Assessments"  } ],
        [ { "id": "a0013", "date": "2022-01-20", "cadence": "Annual", "assessmentName": "FL Risk Assessment"  } ]
    ]
  },
  {
    "partnerId": "p0002",
    "partnerName": "Bar",
    "assessments": [
        [ { "id": "a004", "date": "2021-03-20", "cadence": "Semi-Annual", "assessmentName": "Model Governance" } ],
        [ { "id": "a003", "date": "2021-11-19", "cadence": "Quarterly", "assessmentName": "Credit Strategy"  } ],
        [ { "id": "a003", "date": "2022-05-19", "cadence": "Quarterly", "assessmentName": "Credit Strategy"  } ],
        [ { "id": "a003", "date": "2020-10-29", "cadence": "Quarterly", "assessmentName": "Credit Strategy"  } ],
        [ { "id": "a0001", "date": "2021-11-30", "cadence": "Semi-Annual", "assessmentName": "Counterparty & Financial Risk Assessments"  } ],
        [ { "id": "a0001", "date": "2022-06-07", "cadence": "Semi-Annual", "assessmentName": "Counterparty & Financial Risk Assessments"  } ],
        [ { "id": "a0013", "date": "2022-01-20", "cadence": "Annual", "assessmentName": "FL Risk Assessment"  } ]
    ]
  }
]
</script>

CodePudding user response:

The issue with your current code is that it's not saving the values of cadence and assessmentName from each object, so they will end up undefined in the final object. You can fix this by storing the entire object in a[id] rather than just the date. Once you have done that you can use Object.values rather than Object.entries on the result of the reduce and just use map to put those values into their own array to achieve the nested structure of the input.

const result = data.map(({assessments, ...rest}) => ({
  ...rest,
  'assessments' : Object.values(assessments
    .reduce((a, [obj]) => {
      const { id, date } = obj
      a[id] = (a[id]?.date || '').localeCompare(date) > 0 ? a[id] : obj
      return a
    }, {}))
    .map(obj => [obj])
}))

console.log(result)
<script>
const data = [
  {
    "partnerId": "p0001",
    "partnerName": "Foo",
    "assessments": [
        [ { "id": "a0016", "date": "2021-03-20", "cadence": "Annual", "assessmentName": "FFIEC CAT Survey" } ],
        [ { "id": "a0016", "date": "2021-11-19", "cadence": "Annual", "assessmentName": "FFIEC CAT Survey"  } ],
        [ { "id": "a0011", "date": "2022-05-19", "cadence": "Annual", "assessmentName": "FCC Risk Assessment"  } ],
        [ { "id": "a0011", "date": "2020-10-29", "cadence": "Annual", "assessmentName": "FCC Risk Assessment"  } ],
        [ { "id": "a0001", "date": "2021-11-30", "cadence": "Semi-Annual", "assessmentName": "Counterparty & Financial Risk Assessments"  } ],
        [ { "id": "a0001", "date": "2022-06-07", "cadence": "Semi-Annual", "assessmentName": "Counterparty & Financial Risk Assessments"  } ],
        [ { "id": "a0013", "date": "2022-01-20", "cadence": "Annual", "assessmentName": "FL Risk Assessment"  } ]
    ]
  },
  {
    "partnerId": "p0002",
    "partnerName": "Bar",
    "assessments": [
        [ { "id": "a004", "date": "2021-03-20", "cadence": "Semi-Annual", "assessmentName": "Model Governance" } ],
        [ { "id": "a003", "date": "2021-11-19", "cadence": "Quarterly", "assessmentName": "Credit Strategy"  } ],
        [ { "id": "a003", "date": "2022-05-19", "cadence": "Quarterly", "assessmentName": "Credit Strategy"  } ],
        [ { "id": "a003", "date": "2020-10-29", "cadence": "Quarterly", "assessmentName": "Credit Strategy"  } ],
        [ { "id": "a0001", "date": "2021-11-30", "cadence": "Semi-Annual", "assessmentName": "Counterparty & Financial Risk Assessments"  } ],
        [ { "id": "a0001", "date": "2022-06-07", "cadence": "Semi-Annual", "assessmentName": "Counterparty & Financial Risk Assessments"  } ],
        [ { "id": "a0013", "date": "2022-01-20", "cadence": "Annual", "assessmentName": "FL Risk Assessment"  } ]
    ]
  }
]
</script>

  • Related