0

I am new to React and I load all the data from my database initially on page load but there is info I need to find in an array and apparently it isn't instant. What do I need to do to make sure the render method only renders the objects when the object promises have resolved?

I haven't tried much... I'm really stuck here.

This seems different than the other problems I've read here because I load a bunch on info in the beginning just fine but I need to call some team information every time a function is called so it isn't as simple as loading it once because the object i need is always different.

This code is the main issue. I also included the full file below:

I did some modification to the code in a edit: I realized that I just need to call the opponent team because I have the player team already.

 if (team.id === game.team_1) {
    var redTeam = team;

    // set blueTeam based on game.team_1
    // firebase.teams().doc('teams/{game.team_2}')
  } else {
    var blueTeam = team;

    // set redTeam based on game.team_1
    // firebase.teams().doc('teams/{game.team_1}')

  }

Full file:

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import Async from 'react-promise'

import { withFirebase } from '../Firebase';
// import * as ROUTES from '../../constants/routes';

import { Container, Image, Spinner, Col, Row, Card, Accordion, Button } from 'react-bootstrap'

class PlayerGameList extends Component {
  constructor(props) {
    super(props);

    this.state = {
      loadingTeams: false,
      loadingSchedule: false,
      teams: [],
      schedule: []
    };
  }

  componentDidMount() {
    this.setState({
      loadingTeams: true,
      loadingSchedule: true,
    });

    this.unsubscribe = this.props.firebase
      .teams()
      .where('players', 'array-contains', '-LXkkB7GNvYrU4UkUMle')
      .onSnapshot(snapshot => {
        let teams = [];

        snapshot.forEach(doc =>
          teams.push({ ...doc.data(), uid: doc.id }),
        );

        this.setState({
          teams,
          loadingTeams: false,
        });
      });

    this.unsubscribe2 = this.props.firebase
      .schedule()
      .onSnapshot(snap => {
        let schedule = [];

        snap.forEach(doc =>
          schedule.push({ ...doc.data(), uid: doc.id }),
        );

        this.setState({
          schedule,
          loadingSchedule: false,
        });
      });
  }

  componentWillUnmount() {
    this.unsubscribe();
    this.unsubscribe2();
  }

  render() {
    const { teams, schedule, loadingTeams, loadingSchedule } = this.state;

    return (
      <div>
        <h2>Games</h2>
        {loadingTeams && loadingSchedule && <div colSpan="12"><Spinner animation="border" role="status">
          <span className="sr-only">Loading...</span>
        </Spinner></div>}

        {/* CONTENT */}
        <Container fluid>
          <Row>
            {getTeams({ teams, schedule })}
          </Row>
        </Container>
      </div >
    );
  }
}

function getTeams({ teams, schedule }) {

  if (!teams) {
    return null;
  }

  if (!teams.length) {
    return null;
  } else {
    return teams.map(team => getGames({ team, schedule }))
  }
}

function getGames({ team, schedule }) {
  schedule.sort((a, b) => (a.time > b.time) ? -1 : 1)

  if (!schedule) {
    return null;
  }

  if (!schedule.length) {
    return null;
  } else {
    return schedule.map(game => guts({ team, game }));
  }
}

function guts({ team, game }) {
  const image = {
    height: '25px',
    width: '25px'
  }

  if (team.id === game.team_1) {
    var redTeam = team;

    // set blueTeam based on game.team_1
    // firebase.teams().doc('teams/{game.team_2}')
  } else {
    var blueTeam = team;

    // set redTeam based on game.team_1
    // firebase.teams().doc('teams/{game.team_1}')

  }


  if (game.team_1 === team.id || game.team_2 === team.id) {
    var time = new Date(game.time.seconds * 1000);
    var dateFormat = require('dateformat');
    var finalTime = dateFormat(time, 'ddd mmm dd, h:MM tt')

    return (
      <Col lg='4' md='6' sm='12' key={game.uid} style={{ marginBottom: '15px' }}>
        <Card>
          <Card.Body>
            <Row>
              <Image src={team.logo} style={image} roundedCircle />
              <p>{team.name}</p>
              <div style={{ height: '25px', width: '25px', backgroundColor: 'red' }}></div>
            </Row>
            <Row>
              <Image src={team.logo} style={image} roundedCircle />
              <p>{team.name}</p>
              <div style={{ height: '25px', width: '25px', backgroundColor: 'blue' }}></div>
            </Row>
            <Row>
              <div>
                {finalTime}
              </div>
            </Row>
          </Card.Body>
          <Accordion>
            <Card style={{ margin: '0', padding: '0' }}>
              <Card.Header>
                <Accordion.Toggle as={Button} variant="link" eventKey="0">
                  Show Match IDs
                  </Accordion.Toggle>
              </Card.Header>
              <Accordion.Collapse eventKey="0">
                <Card.Body>{game.match_id}</Card.Body>
              </Accordion.Collapse>
            </Card>
          </Accordion>
        </Card>
      </Col>
    );
  }
}

export default withFirebase(PlayerGameList);

The items all load blank then a few seconds later all the console logs come through with the array objects. When I tell it to await the program just throws an error.

new Q Open Wid
  • 2,225
  • 2
  • 18
  • 34
hefty_kat
  • 211
  • 4
  • 15
  • 1
    Possible duplicate of [Rendering React components with promises inside the render method](https://stackoverflow.com/questions/33242378/rendering-react-components-with-promises-inside-the-render-method) – Tarun Kolla Aug 31 '19 at 18:14
  • @TarunKolla I read that one but I am doing things 'on the fly it seems' I am using this method for the "teams, schedule, allTeams" portion but I need the section highlighted above to product a result every time the function is called and not just at the beginning of the initial state. I thought my answer might be slightly different? – hefty_kat Aug 31 '19 at 18:32
  • @hefty_kat Please post your question and answer separately, else this will be deleted as "not a question". – new Q Open Wid Sep 01 '19 at 17:55
  • @zixuan I haven't solved it? – hefty_kat Sep 04 '19 at 02:15
  • No, listen to my comments. – new Q Open Wid Sep 04 '19 at 19:27
  • do you mean read? it isn't an audio file. – hefty_kat Sep 05 '19 at 04:17

0 Answers0