0

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!

1
  • Update your filter calls to filter(card => card.status === "todo") and the mapping within List render to be Title={card.title} Commented Dec 11, 2017 at 22:30

1 Answer 1

1

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>
    );
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

In Dashboard render() function, I cant change from card.props.status to card.status, as the child component take in props a Card object (which already is a react component class extension)
Your Dashboard state property Cards should have the shape of an array containing objects shaped like the JSON response. Call it CardData so you don't mix it up with Card component. Hope this is clear.
still doesnt render card components

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.