-1

How to display complex json object with following response,

const movie = "AVTAR";
const displayData = {
   "actor": [{
      "id": 1,
      "name": "john"
   }, {
      "id": 2,
      "name": "peter"
   }],
   "actress": [{
      "id": 1,
      "name": "ema"
   }, {
      "id": 2,
      "name": "molly"
   }]
}

on UI I need to show like,

Avatar >> actor >> john
Avatar >> actor >> peter
Avatar >> actress >> ema
Avatar >> actress  >>molly

I am using react functional component with es map function

sourabh k
  • 33
  • 4
  • 1
    You should _attempt_ to write something yourself, and then come back here if you run into problems - posting your code as a [mcve]. PS it might help you code this if you had a more straightforward data structure like a single array of objects. – Andy Jan 26 '23 at 07:25
  • Single array of object is not possible as it is sending data in above format – sourabh k Jan 26 '23 at 07:30
  • You can make it single array of objects perhaps, and use that as your starting point. Your question is about the complexity of the data. One solution would be to make it simpler to work with. – Andy Jan 26 '23 at 07:32
  • but I need to display like this,Avatar >> actor >> john Avatar >> actor >> peter Avatar >> actress >> ema Avatar >> actress >>molly It would be helpful if you help me with code as i am new to react and Javascript – sourabh k Jan 26 '23 at 07:41
  • You need to flatten the `displayData` object and transform it into an array, that way will be much simpler to render the data the way you want it, that is one of many ways to go about it. [This post](https://stackoverflow.com/questions/34513964/how-to-convert-this-nested-object-into-a-flat-object) has many examples on solving this issue. – Ricardo Sanchez Jan 26 '23 at 08:20
  • @sourabhk I had a think about this because it's more complex than I realised, so I wrote a solution which may help. – Andy Jan 26 '23 at 08:41

2 Answers2

0

So based on the description you're creating little breadcrumbs for each cast member of a movie. Because each breadcrumb will need a unique id it's always better to wrangle the data to ensure that this is possible rather than use the map iteration id in the component. This will also ensure that you get to make very simple components which are easy to test.

So in order to do that we need to change the data from that complex model to a simpler one: an array of objects that we can iterate over, and each object will have its own unique id (at the moment they don't - actors and actresses share ids at the moment).

There are two steps to that:

  1. Add the cast member role to each of their objects
  2. Re-id all of the objects so each is unique.

Let's start with that first.

const data={actor:[{id:1,name:"john"},{id:2,name:"peter"}],actress:[{id:1,name:"ema"},{id:2,name:"molly"}]};

// For each cast member add their role (actor/actress)
// Do this by mapping over an array, and then
// returning a new object that includes the type
function addRole(data, type) {
  return data[type].map(n => {
    return { ...n, type };
  });
}

// Re-id all of the cast information
// Flatten the arrays, map over them, and return a
// new array where each object has a consecutive id
function reId(arrs) {
  return arrs
    .flat()
    .map((n, id) => {
      return { ...n, id: id + 1 };
    });
}

// Add all that together
const wrangled = reId([
  addRole(data, 'actor'),
  addRole(data, 'actress')
]);

console.log(wrangled);

Once you've done that you can throw the title and the wrangled data into the component, and then build the breadcrumbs for each movie's cast member.

// Accepts a title, and some wrangled data
// We `map` over the data and for each cast member
// we use the Breadcrumb component to
// generate a breadcrumb for that cast member
// Note we use the new generated id as each breadcrumb key
function Movie({ title, data }) {
  return (
    <section>
      {data.map(char => {
        return (
          <Breadcrumb
            key={char.id}
            title={title}
            char={char}
          />
        )
      })}
    </section>
  );
}

// Breadcrumb accepts a title, and the character data
// and produces an inline list breadcrumb for that character
function Breadcrumb({ title, char }) {
  return (
    <ul>
      <li>{title}</li>
      <li>{char.type}</li>
      <li>{char.name}</li>
    </ul>
  );
}

const data={actor:[{id:1,name:"john"},{id:2,name:"peter"}],actress:[{id:1,name:"ema"},{id:2,name:"molly"}]};

function addRole(data, type) {
  return data[type].map(n => ({ ...n, type }));
}

function reId(arrs) {
  return arrs.flat().map((n, id) => ({ ...n, id: id + 1 }));
}

const wrangled = reId([ addRole(data, 'actor'), addRole(data, 'actress') ]);

ReactDOM.render(
  <Movie title="Avatar" data={wrangled} />,
  document.getElementById('react')
);
ul { list-style: none; margin-left: 0; padding-left: 0;}
li { display: inline; text-transform: uppercase;}
li:first-child { color: red; }
li:not(:last-child)::after { content: ' >> '; color: black;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Andy
  • 61,948
  • 13
  • 68
  • 95
0

I like to learn from looking at code examples, and when I started I also struggle, hope this helps.

// First flat the displayData object into an array of objects in the form { type, id, name }
const flatData = Object.entries(displayData).flatMap(([k, v]) => {
    // Because type (actor / actress) is an array we have to iterate over its keys and values
    const inner = v.map(({id, name}) => {
        // Return an object with typem, id and name
        return {type: k, id, name};
    });
    // return the previously constructed object
    return inner;
    // Flattens the array
}).flat();

// Iterate the data and display its content
flatData.forEach( (data) => {
    // Destructure the values from the data object
    const {type, id, name} = data
    console.log(`${movie} >> ${type} >> ${name}`);  
});

Any questions just ask.

Ricardo Sanchez
  • 4,935
  • 11
  • 56
  • 86