Как передать данные ответа axios в vue 3 с помощью axios all

#javascript #vue.js #axios

Вопрос:

Я пытаюсь выполнить несколько запросов с помощью axios и сохранить ответ в реквизите vue 3. Я знаю, что реквизит не мутирует, но это другой разговор. Поскольку translation это объект (переменная передается по ссылке), ее изменение должно быть возможно здесь.

Как я правильно понял, он axios.all() выполняет несколько асинхронных запросов одновременно. Код здесь работает правильно, запрос axios выполнен успешно, и я могу console.log(response.data) выполнить их в then() коде. Пока все хорошо.

Что абсолютно не работает, так это эта строка: this.translation[Object.keys(response.data)[index]] = response.data; — Опора translation не будет изменена, и я не получаю никаких ошибок в консоли, но, как я написал, в консоли появляется текст «отправлены все вызовы axois».

Если я изменю опору перед вызовом axios, например this.translation["foo"] = { bar: "foo" } , это сработает.

Что я здесь делаю не так? Как я могу передать данные здесь из axios-ответа в переменную prop translation ?

 export default {
  props: {
    marketplaces: Object,
    translation: Object,
  } 
}
 
 let requests = [axios1, axios2, ...]

axios
    .all(requests)
    .then(
        axios.spread((...responses) => {
            responses.forEach((response, index) => {
                this.translation[Object.keys(response.data)[index]] = response.data;
            });
            console.log("submitted all axios calls");
        })
    )
    .catch((error) => {
        console.log("ERRRR:: ", error.response.data);
    });
 

Комментарии:

1. FWIW, все и распространение устарели. Эти функции существуют в JS уже давно.

2. У вас есть какие-нибудь подсказки, как использовать несколько запросов в 2021 году?

Ответ №1:

Итак, теперь я перешел на код, подобный тому, который показывают новейшие документы axios для нескольких запросов на публикацию, и изменил эту строку .then((results) => { , чтобы теперь this область действия была правильной.

 export default {
  props: {
    marketplaces: Object,
    translation: Object,
  } 
}

let requests = [axios1, axios2, ...]

Promise.all(requests)
.then((results) => {
  results.forEach((result, index) => {
    // I get the CORRECT result here
    console.log("BEFORE:");
    console.log(this.translation);

    this.translation[Object.keys(result.data)[index]] = result.data;

    console.log("AFTER:");
    console.log(this.translation);
  });
})
 

Я поставил a console.log ДО и ПОСЛЕ изменения объекта this.translation , и действительно, объекты, похоже, мутировали в консоли.войдите, но не в Vue-Dev-Инструменты. Итак, я должен изменить что-то еще, имеет ли это какое-то отношение к mounted() тому, что происходит в Vue?

Комментарии:

1. Должен ли я привязываться this где-либо здесь в вызове axios?

2. Обещание.все и т. Д.-Это то, как это должно быть сделано. Вы хотите сказать, что поместили это за пределы компонента? Тогда это ошибка. Это должно быть сделано внутри.

3. Если я помещу блок ниже экспорта (так что перед axios), например: this.translation[«foo»] = { bar: «foo»}, он работает — это ошибка, this там объект модуля.

4. Я помещаю свой ответ ниже.

5. Изменение функции .then(function после обещания.все на функцию со стрелкой не решает проблему области действия this ?

Ответ №2:

 export default {
  // Persistent Layout for Menu and Header
  layout: (h, page) => h(Layout, [page]),
  layout: BreezeAuthenticatedLayout,

  components: {
    BreezeAuthenticatedLayout,
    FormButton,
    FormInput,
    FormSelect,
    FormRadio,
    MarketplaceForm,
  },

  setup() {
    const form = useForm({
      asin: "1234567890", //null,
      sourceMarketplace: "de", //null,
      formality: "default",
    });

    return { form };
  },
  props: {
    marketplaces: Object,
    translation: Object,
  },
  methods: {
    submit() {
      this.form.post(
        "/translation/fetch-listing",
        {
          onSuccess: (page) => {
            console.warn("Now translate:");
            this.translateAll();
          },
        }
      );
    },
    translateAll() {
      let requests = [];
      Object.keys(this.marketplaces).forEach((value, index) => {
        if (this.form.sourceMarketplace === value) return;

        let postData = {
          sourceMarketplace: this.form.sourceMarketplace,
          targetMarketplace: value,
          formality: this.form.formality,
          translation: this.translation,
        };

        let newPromise = axios({
          method: "post",
          url: "/translation/translate",
          data: postData,
        });

        requests.push(newPromise);
      });

      Promise.all(requests)
        .then((results) => {
          results.forEach((result, index) => {
            console.log(index);
            console.log("translation before: ");
            console.log(this.translation);
            this.translation[Object.keys(result.data)[index]] =
              result.data[Object.keys(result.data)[index]];
            console.log("translation after: ");
            console.log(this.translation);
          });
        })
        .catch((error) => {
          console.log("Axios error: ");
          console.error(error);
        });
    },
  },
};
</script>