krezeee
krezeee

Reputation: 3

Typescript react fetching undefined objects

I've got some issues feeding my components with sample data. I have created a web api method that returns some json objects:

[ {"id":1,"title":"Master framework","description":"A framework to develope advance UI interfaces for modern web applications","status":"in-progress","color":"#3A7E26"}, {"id":2,"title":"Setup main app solution","description":"An app ","status":"todo","color":"#3A7E26"}, {"id":3,"title":"UI mock creation","description":"Have to be neat a simple","status":"todo","color":"#BD8D31"}, {"id":4,"title":"WebAPI implementation","description":"Based on REST architecture","status":"todo","color":"#BD8D31"} ]

My components: Dashboard:

interface IDashboardState {
    Cards: Card[];
}

export class Dashboard extends React.Component<RouteComponentProps<{}>, IDashboardState> {
    constructor() {
            super();
            this.state = { Cards: [] };
    }

    public componentDidMount() {

        const baseUrl = 'http://localhost:51429/Home/Cards';
        var cardEntities: CardEntity[];

        fetch(baseUrl)
            .then((response) => (response.json())
                .then((responseData) => {
                    console.log(responseData.length);
                    this.setState({ Cards: responseData })
                })
                .catch((error) => {
                    console.log("Error loading data", error);
                }));

    }

    render() {
        return (
            <div className="app">
                <List Id='todo' Title="To do" Cards={
                    this.state.Cards.filter((card) => card.props.Status === "todo")}
                     />
                <List Id='in-progress' Title="In progress" Cards={
                    this.state.Cards.filter((card) => card.props.Status === "in-progress")}
                     />
                <List Id='done' Title="Done" Cards={
                    this.state.Cards.filter((card) => card.props.Status === "done")}
                     />
            </div>
        );
    }
}

List:

interface IListProps {
    Id: string;
    Title: string;
    Cards: Card[];
}
export class List extends React.Component<IListProps, {}> {
    render() {
        var cards = this.props.Cards.map((card => {
            return <Card key={card.props.Id}
                Id={card.props.Id}
                Title={card.props.Title}
                Description={card.props.Description}
                Status={card.props.Status}
                Color={card.props.Color}
                />
        }))

        return (
            <div className="list">
                <h1>{this.props.Title}</h1>
                {cards}
            </div>
        );
    }
}

Card:

interface ICardProps {
    Id: number;
    Title: string;
    Description: string;
    Status: string;
    Color: string;
}

interface ICardState {
    showDetails: boolean;
}


export class Card extends React.Component<ICardProps, ICardState> {
    constructor(props: ICardProps) {
        super(props)
            this.state = {
        showDetails: false
    };
}

toggleDetails() {
    this.setState({showDetails: ! this.state.showDetails})
}

render() {

    let cardDetails;
    if (this.state.showDetails) {
        cardDetails = (
            <div className="card_details">
                <CheckList CardId={this.props.Id}

                />
            </div>
        );
    }

    return (
        <div className="card">
            <div>
                <div className="card_title" onClick={this.toggleDetails.bind(this)}>
                    {this.props.Title}
                </div>
                <div className="card_description">
                    {this.props.Description}
                </div>
                {cardDetails}
            </div>
        </div>
    );
}

I thought react while fetching would automatically assign my json to Card object, but it leaves them as undefined and no content is rendered. Any ideas why?

Thanks for help in advance!

Upvotes: 0

Views: 1752

Answers (1)

arpl
arpl

Reputation: 3633

The response data are not mapped correctly to props.

Dashboard

interface CardData {
  id: string;
  title: string;
  description: string;
  status: string;
  color: string;
}

interface IDashboardState {
  cards: CardData[];
}

export class Dashboard extends React.Component<RouteComponentProps<{}>, IDashboardState> {
  constructor() {
    super();
    this.state = { cards: [] };
  }

  public componentDidMount() {

    const baseUrl = 'http://localhost:51429/Home/Cards';
    var cardEntities: CardEntity[];

    fetch(baseUrl)
      .then((response) => (response.json())
        .then((responseData) => {
          console.log(responseData.length);
          this.setState({ cards: responseData as CardData[] })
        })
        .catch((error) => {
          console.log("Error loading data", error);
        }));

  }

  render() {
    return (
      <div className="app">
        <List Id='todo' Title="To do" Cards={
          this.state.cards.filter((card) => card.status === "todo")}
        />
        <List Id='in-progress' Title="In progress" Cards={
          this.state.cards.filter((card) => card.status === "in-progress")}
        />
        <List Id='done' Title="Done" Cards={
          this.state.cards.filter((card) => card.status === "done")}
        />
      </div>
    );
  }
}

List

interface IListProps {
  Id: string;
  Title: string;
  Cards: Card[];
}

export class List extends React.Component<IListProps, {}> {
  render() {
    var cards = this.props.Cards.map(card => {
      return
        <Card key={card.id}
          Id={card.id}
          Title={card.title}
          Description={card.description}
          Status={card.status}
          Color={card.color}
        />
    })

    return (
      <div className="list">
        <h1>{this.props.Title}</h1>
        {cards}
      </div>
    );
  }
}

Upvotes: 1

Related Questions