Home > Software design >  Unable to implement Loader
Unable to implement Loader

Time:09-25

I'm new to react.js Please help me to find what I'm doing wrong I'm getting the list of items from API and I want to implement a Loader while loading the data. I'm using if statement if as you can see in the code. Is there another way to achieve the similar thing. This is how I'm doing...

import React, { useState, useEffect } from "react";
import { ListGroup, Row, Card, Container, Col } from "react-bootstrap";
import Loader from "../components/Loader";

const fetchURL = "api/guide/";
const getItems = () => fetch(fetchURL).then((res) => res.json());

function Guide() {
  
    const [items, setItems] = useState([]);
    useEffect(() => {
        getItems().then((data) => setItems(data));
    }, []);
    return (
        <Row>
            <Container fluid>
                {items ? (
                    items.map((item) => (
                        <ListGroup
                            className="mb-3 my-3 p-1 rounded"
                            variant="success"
                        >
                            <ListGroup.Item
                                style={{
                                    width: "auto",
                                    height: "auto",
                                }}
                                className="mb-2 my-2 p-2 rounded"
                                variant="flush"
                            >
                                <Row>
                                    <Col md="7">
                                        <h3 className="mx-3">
                                            <strong>{item.title}</strong>
                                        </h3>

                                        <Card.Body>
                                            <p>{item.description}</p>
                                        </Card.Body>
                                    </Col>
                                    <Col md="5">
                                        {item.ytVidLink ? (
                                            <Card className="my-2 p-2 rounded card border-light">
                                                {" "}
                                                <div className="video-responsive">
                                                    <iframe
                                                        width="1200"
                                                        height="720"
                                                        src={`https://www.youtube.com/embed/${item.ytVidLink}`}
                                                        frameBorder="0"
                                                        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                                                        allowFullScreen
                                                        title="Embedded youtube"
                                                    />
                                                </div>
                                            </Card>
                                        ) : (
                                            <div variant="light"> </div>
                                        )}
                                    </Col>
                                </Row>
                            </ListGroup.Item>
                        </ListGroup>
                    ))
                ) : (
                    <Loader />
                )}
            </Container>
        </Row>
    );
}

export default Guide;

Data coming as expected but Loader is loading as I want.

CodePudding user response:

import React, { useState, useEffect } from "react";
import { ListGroup, Row, Card, Container, Col } from "react-bootstrap";
import Loader from "../components/Loader";

const fetchURL = "api/guide/";
const getItems = () => fetch(fetchURL).then((res) => res.json());

function Guide() {
  
    const [items, setItems] = useState([]);
    const [loading, setLoading] = useState(true)
    useEffect(() => {
      getItems().then((data) => {
        setItems(data);
        setLoading(false);
      });
    }, []); 
    return (
        <Row>
            <Container fluid>
                {items ? (
                    items.map((item) => (
                        <ListGroup
                            className="mb-3 my-3 p-1 rounded"
                            variant="success"
                        >
                            <ListGroup.Item
                                style={{
                                    width: "auto",
                                    height: "auto",
                                }}
                                className="mb-2 my-2 p-2 rounded"
                                variant="flush"
                            >
                                <Row>
                                    <Col md="7">
                                        <h3 className="mx-3">
                                            <strong>{item.title}</strong>
                                        </h3>

                                        <Card.Body>
                                            <p>{item.description}</p>
                                        </Card.Body>
                                    </Col>
                                    <Col md="5">
                                        {item.ytVidLink ? (
                                            <Card className="my-2 p-2 rounded card border-light">
                                                {" "}
                                                <div className="video-responsive">
                                                    <iframe
                                                        width="1200"
                                                        height="720"
                                                        src={`https://www.youtube.com/embed/${item.ytVidLink}`}
                                                        frameBorder="0"
                                                        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                                                        allowFullScreen
                                                        title="Embedded youtube"
                                                    />
                                                </div>
                                            </Card>
                                        ) : (
                                            <div variant="light"> </div>
                                        )}
                                    </Col>
                                </Row>
                            </ListGroup.Item>
                        </ListGroup>
                    ))
                ) : ''}
                
                 {loading ? <Loader /> : ''}
                
            </Container>
        </Row>
    );
}

export default Guide;

Added a loading state and initially, its value is true. so it will show loading and after getting the data from API we will change loading state to false

by using this method even if your API returns empty results it will work very fine. but in your method, if you get an empty result from API it will not stop loading!

CodePudding user response:

You're initializing items to an empty array which will evaluate to true in a boolean context. So your condition (items ?) is always true. You could test items.length instead.

  • Related