0

I'm converting an object into an array but TypeScript throws and error:

"Property 'map' does not exist on type 'unknown'"

(Yes, I googled that error but nothing very clear on the web)

Live Demo

In this live demo you will not see the TypeScript error but in my Angular app I can see it and it's causing issues.

How can I convert this object to the same array shown on my live demo using Lodash or JavaScript?

This is the code:

dataObject = {
A: [
    {id: 1, name: 'Mike', lastname: 'asmith'},
    {id: 2, name: 'Mary', lastname: 'alters'},
    {id: 3, name: 'Boris', lastname: 'al'}
],
B: [
    {id: 1, name: 'Lauren', lastname: 'bmith'},
    {id: 2, name: 'Travis', lastname: 'balters'},
    {id: 3, name: 'Barn', lastname: 'bl'}
], 
...
}
  
dataObjectDisp = Object.entries(this.dataObject).reduce((prev, [key, value]) =>{
  return [...prev, ...value.map((user, index) => ({ 
    ...user, parent: key, index }))]
}, []);

This is the output that I want:

 [
  {
    "id": 1,
    "name": "Mike",
    "lastname": "asmith",
    "parent": "A",
    "index": 0
  },
  {
    "id": 2,
    "name": "Mary",
    "lastname": "alters",
    "parent": "A",
    "index": 1
  },
  ...
]
3
  • What is your ES version? Check that you have ES2017 as it was introduced in same. Commented Mar 15, 2021 at 21:53
  • value is type of object and map is only available if it is an Array. Commented Mar 15, 2021 at 22:04
  • 1
    Try to add type to value. Change [key, value] to something like [key, value]: [string, Array<{ id: number; name: string; lastname: string; }>] Commented Mar 15, 2021 at 22:08

2 Answers 2

1

TS can't infer the type of Array.reduce() accumulator (the empty array at the end). You can set the accumulator as the type of array you wish to get in the end (TS Playground):

type Obj = {
  "id": number,
  "name": string,
  "lastname": string,
  "parent": string,
  "index": number
};

export class AppComponent implements OnInit {
...
  dataObjectDisp = Object.entries(this.dataObject).reduce((prev, [key, value]) =>{
    return [...prev, ...value.map((user, index) => ({ 
      ...user, parent: key, index }))]
  }, [] as Obj[])   
...
}

Another option is to use Array.flatMap() instead of array reduce, but you'll need to change the target in TS Config to es2019 (TS Playground):

export class AppComponent implements OnInit {
...
  dataObjectDisp = Object.entries(this.dataObject).flatMap(([key, value]) =>
    value.map((user, index) => ({ ...user, parent: key, index }))
  )
...
}

And if you use lodash, you can use _.flatMap(), without changing the target (TS Playground):

import { flatMap } from 'lodash';

export class AppComponent implements OnInit {
...
  dataObjectDisp = flatMap(this.dataObject, (value, key) =>
    value.map((user, index) => ({ ...user, parent: key, index }))
  )
...
}
Sign up to request clarification or add additional context in comments.

Comments

0

you can iterate through objects keys and get your result this way

var dataObject = {
  A: [{
      id: 1,
      name: 'Mike',
      lastname: 'asmith'
    },
    {
      id: 2,
      name: 'Mary',
      lastname: 'alters'
    },
    {
      id: 3,
      name: 'Boris',
      lastname: 'al'
    }
  ],
  B: [{
      id: 1,
      name: 'Lauren',
      lastname: 'bmith'
    },
    {
      id: 2,
      name: 'Travis',
      lastname: 'balters'
    },
    {
      id: 3,
      name: 'Barn',
      lastname: 'bl'
    }
  ],
};

const convert = (obj) => {
  var result = [];
  for (var key in obj) {

    result = result.concat(obj[key])
  }
  return result;
}
console.log(convert(dataObject))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.