skip to Main Content

I am making a web application that can search and display movie content and I am trying to get access to outer objects such as "title" with nested objects like "principals" – fetched from the same endpoint.

JSON response from fetch:

{
  "title": "The Match Factory Girl",
  "year": 1990,
  "runtime": 69,
  "genres": [
    "Comedy",
    "Crime",
    "Drama"
  ],
  "country": "Finland, Sweden",
  "principals": [
    {
      "id": "nm0653669",
      "category": "actress",
      "name": "Kati Outinen",
      "characters": [
        "Iris Rukka"
      ]
    },
    {
      "id": "nm0758825",
      "category": "actress",
      "name": "Elina Salo",
      "characters": [
        "Mother"
      ]
    }
  ],
  "ratings": [
    {
      "source": "Internet Movie Database",
      "value": 7.5
    },
    {
      "source": "Rotten Tomatoes",
      "value": null
    },
    {
      "source": "Metacritic",
      "value": null
    }
  ],
  "boxoffice": 0,
  "poster": "https://m.media-amazon.com/images/M/MV5BMmM1ZTZhNDUtYzBkNi00YzQ0LWEyZjItM2M5OTI2ZTU0MDlkXkEyXkFqcGdeQXVyMjI0MjMwMzQ@._V1_SX300.jpg",
  "plot": "A woman's terribly dull life is upended by a one-night stand pregnancy, causing her to seek retribution."
}

My goal is to get the objects in "principles" to render on an AG grid, meanwhile having objects that aren’t nested such as "title", "year", "runtime’ etc. to display on tags.

I have managed to get "principals" to show using useEffect() on an AG grid but I am lost in trying to also get "title" to display.

const [rowData, setRowData] = useState([]);
const columns = [
    {headerName: "Role", field: "role", sortable: true},
    {headerName: "Name", field: "name"},
    {headerName: "Characters", field: "characters"},
  ];


useEffect(() => {
    fetch(`${API_URL}/movies/data/${imdbID}`)
    .then(res => res.json())
    .then(people => people.principals)
    .then(principals => 
      principals.map(person => {
        return {
          role: person.category,
          name: person.name,
          characters: person.characters,
          id: person.id
        }
    }))
    .then(allPeople => setRowData(allPeople))
    .then(test => console.log("ss"))
    .catch(error => console.log(error))
  }, []);


return (
    <div>
        <h1> The title of the movie is... </h1>
        <div className="ag-theme-balham" style={{height: "300px", width: "1100px"}}>
          <AgGridReact columnDefs={columns}  rowData={rowData} pagination={true} paginationPageSize={7}/>
        </div>
    </div>
  )

2

Answers


  1. Store the entire movie object in the state. Get the year, title and create the rows in the body of the component.

    You can wrap the rows mapping with useMemo to avoid mapping it on each render, when movie doesn’t change:

    const [movie, setMovie] = useState(null);
    
    const { title, year, principals } = movie;
    
    useEffect(() => {
      fetch(`${API_URL}/movies/data/${imdbID}`)
      .then(res => res.json())
      .then(setMovie) // store movie in the state
      .catch(error => console.log(error))
    }, []);
    
    const rows = useMemo(() => principals.map(person => ({
      role: person.category,
      name: person.name,
      characters: person.characters,
      id: person.id
    })), [movie])
    
    return (
      <div>
        <h1> The title of the movie is {title} / {year}</h1>
        <div className="ag-theme-balham" style={{height: "300px", width: "1100px"}}>
          <AgGridReact columnDefs={columns}  rowData={rowData} pagination={true} paginationPageSize={7}/>
        </div>
      </div>
    );
    
    Login or Signup to reply.
  2. It’s simple.. You’re only returning principles from your api response. You need to return the whole object with the formatted principles, as follows

    const [rowData, setRowData] = useState([]);
    const [data, setData] = useState({});
    useEffect(() => {
      fetch(`${API_URL}/movies/data/${imdbID}`)
        .then((res) => res.json())
        .then((people) => people)
        .then((people) => {
          return {
            ...people,
            principles: people.principals.map((person) => ({
              role: person.category,
              name: person.name,
              characters: person.characters,
              id: person.id,
            })),
          };
        })
        .then((allPeople) => {
          setData(allPeople);
          setRowData(allPeople.principals);
        })
        .then((test) => console.log('ss'))
        .catch((error) => console.log(error));
    }, []);
    
    return (
      <div>
        <h1> The title of the movie is: {data.title} </h1>
        <div
          className="ag-theme-balham"
          style={{ height: '300px', width: '1100px' }}
        >
          <AgGridReact
            columnDefs={columns}
            rowData={rowData}
            pagination={true}
            paginationPageSize={7}
          />
        </div>
      </div>
    );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search