Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How handle with object keys when we type dynamic objects?

I have some component that can render data of any object, so I use generic here, but I have some
problems here
{field} : {el[field]}
What is correct way handle this in my example

https://codesandbox.io/s/sleepy-thompson-gim2d1?file=/src/App.tsx

I know that we can use something like this {field} : {el[field as SomeInterface]} or just
add some record property into interface, but I still have problem(

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

You can see my code in the link above, and I also leave it here.

type WrapperProps<T> = {
  data: T[];
};

function Wrapper<T extends object>({ data }: WrapperProps<T>) {
  return (
    <div>
      {data.map((el) => {
        return Object.keys(el).map((field) => {
          return (
            <div key={el + field}>
              {field} : {el[field]}  // type error here
            </div>
          );
        });
      })}
    </div>
  );
}

interface IData {
  name: string;
  age: number;
}

interface IData2 {
  email: string;
  passport: string;
}

export default function App() {
  const data1: IData[] = [
    { name: "Alex1", age: 133 },
    { name: "Alex2", age: 33 }
  ];

  const data2: IData2[] = [
    { email: "email", passport: "passport1" },
    { email: "email2", passport: "passport2" }
  ];

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <Wrapper data={data1} />
      <hr />
      <Wrapper data={data2} />
    </div>
  );
}

>Solution :

Change the compilerOptions/lib in tsconfig.json to "es2017", and use Object.entries() that will extract the value directly (sandbox):

{data.map((el) => {
  return Object.entries(el).map(([field, value]) => {
    return (
      <div key={el + field}>
        {field} : {value}
      </div>
    );
  });
})}

Note: the expression el + field would result in "[object object]" + the text of the field, so the key won’t be unique. You should probably use specific value of each object (id for example) as a basis for the key. Furthermore, you should also use Array.flatMap() to get a single array, and not array of arrays. You can also remove redundant returns, since you’re using arrow functions:

{data.flatMap(el => Object.entries(el).map(([field, value]) => (
  <div key={`${el.id}-${field}`}>
    {field} : {value}
  </div>
)))}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading