Naomi
Naomi

Reputation: 1298

Display content from AJAX request using setState

I'm doing a webapp using github search API. I want the info for each repo to be displayed under the specific repo. I want the content from the AJAX request to be displayed when the specific button is being pressed. I am using React. Since I'm using item.x to access the information I need to get that item and I assume I need to use map but when doing that it will display all the results and not just the specific repository's. Anyway that I can get the Item since it currently says it's undefined?

let searchTerm;

class SearchBox extends React.Component {


    constructor(props) {
        super(props);
        this.onClick = this.onClick.bind(this);
        this.state = { repositories: [],
        showInfo: false };

    }


    render() {
    let moreDetail;
    if(this.state.showInfo){
    moreDetail= <div className="info">                    <li>
                    <p>Open issue count </p>:{item.open_issues_count}
                    </li>
                    <li>
                    <p>Number of forks </p>:{item.forks}
                    </li>
                    <li>
                    <p>Language </p>:{item.language}
                    </li></div>;
    }
        return(
            <div>
                <form>
                <input type="text" className="searchbox"  ref={(input) => { this.searchBox = input; }}/>
                <button onClick={this.onClick}>Search</button>
                </form>
                <h2>Repositories</h2>
                <ul>
                { this.state.repositories.map( ( item, index ) => (
                <div key={ index }>
                  <a href={item.html_url}>  <li >
                        { item.name }

                    </li>
                    </a>
                {moreDetail}

                    <button onClick={this._handleClick.bind(this)}>Detailed view</button>
                </div>
                )) }
                </ul>
            </div>
            );
    }

    _handleClick(){
    this.setState({
    showInfo: !this.state.showInfo
    });
    }


    onClick(event) {

        searchTerm = this.searchBox.value;
        let endpoint = 'https://api.github.com/search/repositories?sort=stars&order=desc&q=' + searchTerm;
        console.log(searchTerm);
        fetch(endpoint)
            .then(blob => blob.json())
            .then(response => {
                this.setState({ repositories: response.items });
            });
        event.preventDefault();

    }
}

Upvotes: 0

Views: 77

Answers (1)

Diogo Sgrillo
Diogo Sgrillo

Reputation: 2701

The problem is with context. When you define the moreDetail variable, you don't have item in your context (only during the map function you have that.)

One option is to use the variable moreDetail as a function that receives the item you want to show.

Your render method should look something like:

render() {
    const moreDetail = (item) => ( !this.state.showInfo ? <span /> :
            <div className="info">                    
                <li>
                    <p>Open issue count </p>:{item.open_issues_count}
                </li>
                <li>
                    <p>Number of forks </p>:{item.forks}
                </li>
                <li>
                    <p>Language </p>:{item.language}
                </li>
            </div>
        );

    return (
        <div>
            <form>
            <input type="text" className="searchbox"  ref={(input) => { this.searchBox = input; }}/>
            <button onClick={this.onClick}>Search</button>
            </form>
            <h2>Repositories</h2>
            <ul>
            { this.state.repositories.map( ( item, index ) => (
            <div key={ index }>
              <a href={item.html_url}>  <li >
                    { item.name }

                </li>
                </a>
                {moreDetail(item)}

                <button onClick={this._handleClick.bind(this)}>Detailed view</button>
            </div>
            )) }
            </ul>
        </div>
        );
}

Upvotes: 1

Related Questions