0
votes

Im using react to fetch data from starwars api(https://swapi.co/). It has a homeworld attribute which calls a futher api for fetching the details about homeworld. I've tried using axios.get() inside another axios.get() to fetch the details for "${results.homeworld}" (PFA code), but it doesnt return anything. Not sure why is this happening and even i cant update state even though i change the axios.get request. It's set to my first search i.e Luke skywalker. What should i do for changing state with every request and how to handle the homeworld API inside the inital JSON object.Also i get an error of Unexpected token < in JSON at position 0 , did try online help for that but still the same problem.

import React from "react";
import axios from "axios";

class Axiosa extends React.Component {
  constructor(props) {
    super(props);

    this.state = { data: {}, name: "", homeplanet: "", species: "" };
  }



    fetchStarwars() {
        axios
          .get("https://swapi.co/api/people/3/")
          //.then(results => results.text())
          .then(results => results.json())

          .then(results => {
            let x = `"${results.homeworld}"`;

            console.log(`"${results.homeworld}"`);

            axios
              .get(x)
              .then(resultshomeworld => {
                resultshomeworld.json();
                console.log(resultshomeworld);
              })

              .then(results => {
                this.setState({ homeplanet: results.name });
              });

            this.setState({ data: results, name: results.name, isLoading: false });
          });
      }

      componentDidMount() {
        this.fetchStarwars();
      }

      render() {
        console.log(this.state.homeplanet);
        return (
          <div className="App">
            <span>{this.state.name}</span>
            <div>{this.state.homeplanet}</div>
          </div>
        );
      }
    }

    export default Axiosa;
3
You haven't returned resultshomeworld.json(); and hence the next, .then won't have the correct promise to executeShubham Khatri

3 Answers

0
votes

H have made some changes in your code. You need this in fetchStarwars function, which could be fulfilled via bind as Nitha said, or using arrow function.

See the working sample here

import React from "react";
import axios from "axios";
import {render} from "react-dom"

class Axiosa extends React.Component {
  constructor(props) {
    super(props);

    this.state = { data: {}, name: "", homeplanet: "", species: "" };
  }



    fetchStarwars = () => {
        axios
          .get("https://swapi.co/api/people/3/")
          .then(response => {
            let results = response.data
            let x = results.homeworld;

            this.setState({ data: results, name: results.name, isLoading: false });
            return axios.get(x)
          })

              .then(results => {
                this.setState({ homeplanet: results.data.name });           });
        
      }

      componentDidMount() {
        this.fetchStarwars();
      }

      render() {
        console.log(this.state);
        return (
          <div className="App">
            <span>{this.state.name}</span>
            <div>{this.state.homeplanet}</div>
          </div>
        );
      }
    }


render(<Axiosa />, document.getElementById('root'));
0
votes

Bind fetchStarwars function inside the constructor

constructor(props) {
    super(props);
    this.state = { data: {}, name: "", homeplanet: "", species: "" };
    this.fetchStarwars = this.fetchStarwars.bind(this);
  }
0
votes

Try doing all the stuff from your second then block within the first one, or have the first return Promise.resolve(result.json()); so it can access the reduced promise value.

Do the same thing with the nested second axios call.

fetchStarwars() {
    axios.get("https://swapi.co/api/people/3/")
      .then(result => {
          let results = result.json();
          let x = `"${results.homeworld}"`;

          console.log(`"${results.homeworld}"`);

          axios.get(x)
              .then(results => {
            this.setState({ homeplanet: results.json().name });
          });

          this.setState({
              data: results,
              name: results.json().name,
              isLoading: false
          });
      });
  }

Also, make sure to also bind this to fetchStarwars within the constructor.