Farukh Khan
Farukh Khan

Reputation: 315

Filtering an api response in reactjs

I am pretty new to react. I am using react-redux to call API's with Axios. I have successfully fetched the result using .get. Now I want to make a drop-down filter, in which if one selected should show the result of that particular type. For more convenience, I made a backend where the response is also sending an object i.e. type, which can be Internal or External. For more clarity, the response looks like this.

[
    {
        "id": 0,
        "title": "TestProductForAzure",
        "description": null,
        "owner": "Seeded Company",
        "link": null,
        "url": "http://localhost:54729/api/product/3",
        "type": "Internal",
        "rank": 0,
        "productid": 3
    },
    {
        "id": 0,
        "title": "Official example",
        "description": null,
        "owner": null,
        "link": "/search/product?url=https://support.example.com/en-ae",
        "url": "https://support.example.com/en-ae",
        "type": "External",
        "rank": 0,
        "productid": 0
    },
    {
        "id": 0,
        "title": "Example1 Support",
        "description": null,
        "owner": null,
        "link": "/search/product?url=https://support.example.com/",
        "url": "https://support.example.com/",
        "type": "External",
        "rank": 0,
        "productid": 0
    }
]

With result above you can see I am getting 2 types of results i.e. Internal and External. On the frontend I want to make a dropdown which has options

Internal
External

and based on the selection I want to show the results what user selected, forexample if the user selects Internal only the internal result should be shown. Otherwise by default all the response should be shown like right now.

My .jsx file look like this. The comment Filtering will tell you what I have tried till now, but I am clueless on this. How can I put the dropdown which lets the component to load again and show the selected results. Moreover, in the return I am already filtering out result.type putting Internal ones blue and External ones red.


function onClickHandler(id) {
  console.log("calling Details Product", id);
  detailsProduct(id);
}

export default function SingleSearchResult(props) {


  let result = props.result;
  console.log("Props Single Search", props);
  const bgColor = useState("black");


  //Collapse For External
  const [collapse, setCollapse] = useState(false);

  const toggle = () => setCollapse(!collapse);

  const loading = () => <Spinner color="success" />;

  const onClickHandlerTup = () => {
    cogoToastHelper.success("You liked this Product");
  };

  const onClickHandlerDown = () => {
    cogoToastHelper.warn("You disliked this Product");
  };

  //Filtering
    let Internal_type = this.props.result.filter(function(types) {
    return types.type === "Internal";
  });

  let External_type = this.props.result.filter(function(types) {
    return types.type === "External";
  });



  return (
    <div className="row">
      <div className="s130">
        <div className="col-lg">
          <div className="container">
            <div className=""></div>
            {/* Loader Here ibox-content*/}
            {result.type === "Internal" ? (
              <Link
                value={result.productid}
                to={DoctorProductLocation.path}
                onClick={() => onClickHandler(result.productid)}
                //onClickHandler(result.productid)
              >
                <h3 style={{ color: "#1a0dab" }}>
                  {result.title}
                  <hr></hr>
                </h3>
              </Link>
            ) : (
              //Try With OnClick Function
              <a onClick={toggle} target="_blank">
                <h3 style={{ color: "RED" }}>
                  {result.title}
                  <hr></hr>
                </h3>
              </a>
            )}
            <p className="p1">{result.description}</p>
          </div>

          {result.type === "Internal" ? (
            <Link
              className="iUh30"
              to={DoctorProductLocation.path}
              onClick={() => onClickHandler(result.productid)}
            >
            </Link>
          ) : (
            <Collapse isOpen={collapse}>
              <Card style={{ maxWidth: "100%" }}>
                <CardBody>
                  Source:
                  <a className="iUh30" href={result.url} target="_blank">
                    <a>{result.url}</a>
                  </a>
                </CardBody>
              </Card>
              <Card style={{ maxWidth: "100%" }}>
                <CardBody>
                  <a
                    href={result.url + "subscribe"}
                    style={{ color: "#1a0dab" }}
                    target="_blank"
                  >
                    Subscribe
                  </a>
                  <p>{result.description} </p>
                  <GoThumbsup
                    className="col-4"
                    onClick={onClickHandlerTup}
                  ></GoThumbsup>
                  <GoThumbsdown
                    className="col-4"
                    onClick={onClickHandlerDown}
                  ></GoThumbsdown>
                </CardBody>
              </Card>

              <br></br>
            </Collapse>
          )}

          {/* RANKING */}
          {/* <p className="rank">Visited {result.rank} times</p> */}
        </div>
      </div>
      <Footer></Footer>
    </div>
  );
}






Upvotes: 1

Views: 7741

Answers (1)

Mosh Feu
Mosh Feu

Reputation: 29337

In order to render a component for each item in an array, you should use .map() that except the array and returns a JSX element. Like this:

data.map(item => (
    <div>
      {item.title}
    </div>
))

Inside that, you can use ternary to render one component if true and another if not, Like this:

data.map(item => (
    item.type === 'Internal' ?
    <div className="internal">
      {item.title}
    </div> :
    <div className="external">
      {item.title}
    </div>
))

If you want to filter based on a dropdown's value, you can filter like any array in javascript - .filter() and convert the result using .map(), like this:

.filter(item => !this.state.filter || item.type === this.state.filter)

This is, obviously, a simpler example than your code, but it should works the same.

Working demo: https://stackblitz.com/edit/react-yldai7?file=index.js

Upvotes: 1

Related Questions