Есть ли процесс / практика для замены значения JSON?В частности, замена URL-адреса API значением, предоставленным API - PullRequest
0 голосов
/ 28 января 2019

Я использую API Звездных войн для практики, но натолкнулся на странную ошибку.Я почти уверен, что у меня проблема, но я не знаю достаточно об этих процессах, чтобы найти проблему.

Я создаю карты профиля с этой информацией, но когда я пытаюсь заменитьURL-адрес homeworld с фактическим именем, я не могу изменить значение, которое отображается в моем элементе реакции.

Это уменьшенная версия объекта JSON, которую я получаю из API.

{
  "name": "Luke Skywalker",
  "height": "172",
  "mass": "77",
  "birth_year": "19BBY",
  "gender": "male",
  "homeworld": "https://swapi.co/api/planets/1/",           
},

Я пытался заменить значение url homeworld именем фактического homeworld, прежде чем сохранить его в моем массиве this.state.Я попытался сделать вызовы извлечения из файлов элементов (это не совсем правильно).Поэтому я взломал код и посмотрел, как он меняется с console.log();.Это не самая красивая.

    fetch('https://swapi.co/api/people/')
      .then(response => {
        return response.json();
      })
      .then(array => {
        console.log(array.results);

        Promise.all(array.results.map(character => {
          console.log(character.homeworld)

          let home_url = character.homeworld;
          fetch(home_url)
            .then(home => {return home.json()})
            .then(home_json => character.homeworld = home_json.name)
        }))
        .then(() => {
          console.log(array.results)
          this.setState({characters:array.results})
        });
      });

console.log(); показывает, что значение для homeworld было изменено на строку 'Tatooine'.Это то же самое, вплоть до карты профиля.Так что я ожидал, что это будет значение в карточке, равное 'Tatooine', но я получаю "https://swapi.co/api/planets/1/".

. На данный момент я не знаю, где мой недостаток знаний.Я не уверен, что это проблема с JSON, React, Fetch / Promises.Так что, если кто-то сможет предложить какое-то понимание этого вопроса, это было бы здорово.Я могу добавить больше кода к сообщению, если это необходимо.Ура!

1 Ответ

0 голосов
/ 28 января 2019

Вам нужно что-то возвращать при каждом вызове .then, чтобы продолжать передавать обновленные данные.Также в Promise.all( array.results.map( вы должны возвращать каждый элемент, чтобы у вас не было массива, заполненного undefined.

Вот пример того, как вы можете это сделать (обратите внимание, я рекомендую использоватьasync / await как минимум для секции Promise.all):

componentDidMount() {
  fetch("https://swapi.co/api/people/")
  .then(response => response.json())
  .then(array => {
    console.log(array.results);

    return Promise.all(array.results.map(async character => {
      console.log(character.homeworld);

      const homeUrl = character.homeworld;
      const home = await fetch(homeUrl);
      const homeJson = await home.json();
      return {
        ...character,
        homeworld: homeJson,
      }
    }));
  })
  .then(characters => {
    console.log(characters);
    this.setState({ characters });
  })
}

Снова используя async / await везде:

componentDidMount() {
  this.fetchData();
}

async fetchData() {
  const response = await fetch("https://swapi.co/api/people/");
  const array = await response.json();
  console.log(array.results);

  const characters = await Promise.all(array.results.map(async character => {
    console.log(character.homeworld);

    const homeUrl = character.homeworld;
    const home = await fetch(homeUrl);
    const homeJson = await home.json();
    return {
      ...character,
      homeworld: homeJson,
    }
  }));

  console.log(characters);
  this.setState({ characters });
}

Затем this.state.charactersмассив длины 10. Вот пример элемента:

{
    birth_year: "41.9BBY"
    created: "2014-12-10T15:18:20.704000Z"
    edited: "2014-12-20T21:17:50.313000Z"
    eye_color: "yellow"
    films: (4) ["https://swapi.co/api/films/2/", "https://swapi.co/api/films/6/", "https://swapi.co/api/films/3/", "https://swapi.co/api/films/1/"]
    gender: "male"
    hair_color: "none"
    height: "202"
    homeworld: {name: "Tatooine", rotation_period: "23", orbital_period: "304", diameter: "10465", climate: "arid", …}
    mass: "136"
    name: "Darth Vader"
    skin_color: "white"
    species: ["https://swapi.co/api/species/1/"]
    starships: ["https://swapi.co/api/starships/13/"]
    url: "https://swapi.co/api/people/4/"
    vehicles: []
}
...