Home > database >  How display or hide json data based on a certain condition?
How display or hide json data based on a certain condition?

Time:07-14

I have JSON data that displays movies along with other information about the movie like its viewer rating, but how would I display only the movies that have a rating of 60 or above? I using React.

Here is the JSON data:

{
"movies":[
    {
        "title": "Spiderhead",
        "cover": "https://media1.houstonpress.com/hou/imager/u/slideshow/13574136/hou_art_20220617_spiderhead_header.jpg",
        "description": "In the near future, convicts are offered the chance to volunteer as medical subjects to shorten their sentence. One such subject for a new drug capable of generating feelings of love begins questioning the reality of his emotions.",
        "year": 2022,
        "genre": "Action",
        "length": "1h 46m",
        "viewer_rating":  54, //This movie should not be displayed because its rating is 54
        "critic_rating": 2.0,
        "critiques": [
            {
                    "critic_name": "Roger Ebert",
                    "critic_image": "https://6ft.com/wp-content/uploads/2020/04/roger_ebert_dot_com_logo1.png",
                    "feedback": "“Spiderhead” imagines a different kind of prison system—one with an open-door policy that allows the incarcerated to have their sense of self, to cook for themselves, to work out when they want to. What they sacrifice as punishment is their brain chemistry for science, which is toyed with by Steve Abnesti (Chris Hemsworth), following the orders of a protocol committee hoping to cure the world's problems through dosages. The prisoner has the free will to take an experimental dosage—approved by saying “Acknowledge”—and can be faced with the self-loathing of “Darkenfloxx,” or the immense need to laugh from “Laffodil.” If Abnesti needs them to articulate what they're thinking, he raises the dosage (via a smartphone app) on 'Verbaluce.' These are strange names (from the George Saunders short story Escape from Spiderhead, a first-person account that thrives on casually throwing these words around), and it's sure strange to see Hemsworth play this guy.",
                    "rating": 2
            }
        ]
            
        
    },
    {
        "title": "THE MAN FROM TORONTO",
        "cover": "https://m.media-amazon.com/images/M/MV5BZDM2YjA2ZjAtMmZmMy00NDhjLWJjYWYtYjc4ZGY0YzUzOTMyXkEyXkFqcGdeQXVyMTkxNjUyNQ@@._V1_.jpg",
        "description": "The Man From Toronto has a crackerjack premise and a fine pair of stars, but this toothless comedy mismatches its promising elements and winds up neither funny or thrilling.",
        "year":2022,
        "genre": "Action, Comedy",
        "length": "1h 50m",
        "viewer_rating": "42%",
        "critic_rating": "24%",
        "critiques": [
            {
                "critic_name": "Calum Marsh, New York Times",
                "critic_image": "https://www.asso-sherpa.org/wp-content/uploads/2018/03/new-york-times-logo.jpg",
                "feedback": "Although Hart, as the broadly comic version of the classic Hitchcockian Wrong Man, has a certain goofball charm, his frantic coward routine gets old quickly, with no appreciable change as the action-flick danger continues to escalate.",
                "rating": 3.6
            },{
                "critic_name":"Jay"
            }
        ]
        
    },
    {
        "title": "Public Enemies",
        "cover": "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcRdKrxTlMnQa6f4JJkzTQAO3nIkep-8rqUnRtFUxbbvsIaXitgY",
        "description": "John Dillinger, Baby Face Nelson and Pretty Boy Floyd are gangsters who have terrorised the city. Federal agents try their best to nab them.",
        "year": 2009,
        "genre": "Action, Biography, Crime",
        "length": "2h 20m",
        "viewer_rating": 68,
        "critic_rating": 4,
        "critiques": [
            {
                "critic_name": "Written by Richard Propes The Independent Critic",
                "critic_image: ": "https://static.wixstatic.com/media/62e23c_05f7bcdfba19426287b81a7bd8238260~mv2.jpeg/v1/fill/w_496,h_130,al_c,q_80,usm_0.66_1.00_0.01,enc_auto/The Independent Critic.jpeg",
                "feedback": "While 'Public Enemies' never quite soars to the heights of 'Bonnie & Clyde' or 'The Untouchables,' it is easily one of 2009's most satisfying action dramas for adults. Featuring memorable performances from Depp and Cotillard and a strong supporting cast, 'Public Enemies' is an intelligent and compelling story about a man whose true story is as intriguing as the myth that has enveloped his life long after his death.",
                "rating": 4
            }
        ]
    }
]
}

Here is the code I use to display the JSON data to my HTML

import React from 'react'
import { useEffect } from 'react';
import { useState } from 'react';
import { Link } from 'react-router-dom';
import './App.css'
function Main() {
const [error, setError] = useState(null);
const [isLoaded, setLoaded] = useState(false);
const [items, setItems] = useState([]);
const [query, setQuery] = useState("");
const [filter, setFilter] = useState("");

useEffect(() => {
    fetch(
        "http://localhost:3005/movies"
    )
        .then((res) => res.json())
        .then(
            (result) => {
                setLoaded(true);
                setItems(result);
                console.log(result);
            },
            (error) => {
                setLoaded(true);
                setError(error);
            }
        );
}, []);
  const data = Object.values(items);
  const search_parameters = Object.keys(Object.assign({}, ...data));
  const filter_items = [...new Set(data.map((item) => item.genre))];
  function search(items) {
    return items.filter((item) =>
    item.genre.includes(filter)&&
        search_parameters.some(() =>
            item.title.toString().toLowerCase().includes(query)
        )
    );
}
  if (error) {
    return <div>Error: {error.message}</div>;
  } else if (!isLoaded) {
    return <div>Loading...</div>;
  } else {
    return (
        <>
          <nav className='navbar'>
          <h1 className='page-logo'>WatchMovie</h1>
              <input
                  type="search"
                  name="search-form"
                  id="search-form"
                  className="search-input"
                  placeholder="Search movies..."
                  onChange={(e) => setQuery(e.target.value)}
              />
              <div className="select">
                  <select
                      onChange={(e) => setFilter(e.target.value)}
                      className="custom-select"
                      aria-label="Filter Movies By Genre">
                      <option value="">Filter By Genre</option>
                      {filter_items.map((item) => (
                      <option value={item}>Filter By {item}</option>
                      ))}
                  </select>
                  <span className="focus"></span>
              </div>
          </nav>
         
            <div className='card-wrapper'>  {/* This is where I render the data to the screen */}
            {search(data).map((item)=>(
              <Link key={`${item.title}`} to={`/fulldetails/${item.title}`}>
                <div className="movie-card">
                  <p className="title">{item.title}</p> <br></br>
                  <img src={item.cover} className="card-img"/> <br></br>
              </div>
              </Link>
            ))}
            </div>
        </>
      );
  }

  }

  export default Main

An image of how it's being displayed: JSON data displayed on screen

CodePudding user response:

Edit the search function like this :

function search(items, minRate = 0) {
    return items.filter(item =>
        item.genre.includes(filter) 
        &&
        search_parameters.some(() =>
            item.title.toString().toLowerCase().includes(query)
        )
        &&
        (!item.viewer_rating || item.viewer_rating >= minRate)
    );
}

Know, when you call search give as the second param an int that represent the minimum rate you want to filter with, if you don't give this param it doesn't filter with it ;)

CodePudding user response:

Put this logic in your component return statement to display only the movies that have a viewer rating of 60 , assuming that yourItems is the state that has all the movies:

  • Option 1: You can put an if-else statement in the map() method like so:

    yourItems.map((item) => {
      if(item.viewer_rating >= 60) {
        return <YourMovieCardComponent item={item}/>                        
      } else {
        return null
      }
    })
    
  • Option 2: You can use a filter() method before the map method() like so:

yourItems.filter(item => item.viewer_rating >= 60).map((item) => {return <YourMovieCardComponent item={item}/>})

CodePudding user response:

To answer my question all I did was put this (item.viewer_rating >= 60) in my filter function:

 function search(items) {
    return items.filter((item) =>
    item.viewer_rating >= 60&& //This will exclude any 'movie/object' with a rating that's less than 60
    item.genre.includes(filter)&&
        search_parameters.some(() =>
            item.title.toString().toLowerCase().includes(query)
        )
    );
}
  • Related