Пытаюсь разобраться с axios, обёрнутым в snotify в своём проекте на VueJS. Нашёл пример того, как можно поместить одно в другое, но возникает проблема - как в случае успеха или ошибки выполнить тот или иной код. Ведь внутри Promise
и внутри axios
я не могу обратиться ко внешним функциям vue
. Как быть?
Ниже код запроса axios
к api axios.post('samples',this.sample)
перед этим обернутый в Promise
для того, чтобы snotify
(показывает сообщения пользователяю) во время выполнения запроса анимировал сообщение, что идёт запрос. Когда запрос завершён успешно, внутри axios
вызывается resolve
- отображается сообщение об успехе. Если ошибка, то она отлавливается и выводится сообщение, описанное в reject
.
Мне же нужно не просто показать сообщение об успехе или ошибке пользователю, мне помимо всего прочего нужно произвести кое-какие действия в том и другом случае. Например, если запрос состоялся, то выводится сообщение об успехе и вызывается функция this.test();
Однако я получаю ошибку - функция не вызывается.
<template>
<button type="button" class="btn btn-primary" @click="createSample">
Добавить образец
</button>
</template>
Скрипт:
export default {
name: "sample",
data() { return { sample: {} } },
methods: {
test() {
console.log('it works!');
},
createSample() {
this.$snotify.async('Called with promise', 'Success async', () => {
return new Promise((resolve, reject) => {
return axios.post('samples', this.sample)
.then(function(success) {
success = success.data;
console.log(success); //Ответ сервера отображается. В БД данные есть.
this.test(); //Ошибка. Не может выполнить функцию. Вызывается reject
resolve({
title: 'Успех',
body: 'Новый образец добавлен',
config: { closeOnClick: true }
});
})
.catch(function(error) {
reject({
title: 'Ошибка',
body: 'Что-то пошло не так',
config: { closeOnClick: true }
})
});
});
});
},
}
}
Рабочий пример на jsfiddle прилагается.
Вам просто нужно пробросить this
внутрь функции промиса. Ваш HTML остается без изменений, таким как и был ранее:
<div id="app">
<button type="button" class="btn btn-primary" @click="createSample">
Добавить образец
</button>
<vue-snotify></vue-snotify>
</div>
Вот JS немного поменяется (за основу взят ваш код из JsFiddle):
const app = new Vue({
el: '#app',
methods: {
test() {
console.log('it works!');
},
createSample() {
this.$snotify.async('Called with promise', 'Success async', () => {
return new Promise((resolve, reject) => {
return axios.get('https://jsonplaceholder.typicode.com/users')
.then(function(success) {
success = success.data;
console.log(success); // Ответ сервера
this.test(); // После того, как сделали bind(this) - ошибки не будет
resolve({
title: 'Успех',
body: 'Новый образец добавлен',
config: {
closeOnClick: true
}
});
}.bind(this)) // вот тут мы пробросили this внутрь
.catch(function(error) {
reject({
title: 'Ошибка',
body: 'Что-то пошло не так',
config: {
closeOnClick: true
}
})
});
});
});
},
}
});
Все решилось с помощью добавления .bind(this)
к функции, которая выполняется внутри then
. Если не выполнить bind
, то this
внутри функции - это всего лишь область функции.
Также, есть еще более простой вариант - это стрелочная функция. Стрелочные функции при создании привязываются к текущему значению this
. Поэтому код станет немного современнее и проще (на примере then
, где вызывается функция test
):
.then((success) => {
success = success.data;
console.log(success); // Ответ сервера
this.test(); // Можем выполнить эту функцию
resolve({
title: 'Успех',
body: 'Новый образец добавлен',
config: {
closeOnClick: true
}
});
})
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Начинающий в js прошу сильно не пинать) функция по клику создает заголовок h4, так же вместе с заголовком создается ссылка с кнопкой удаления...
Имеется input с подключенным bootstrap datetimepickerТакже задается defaultDate в котором дата задается с помощью moment
Есть два списка и в каждом одинаковое количество optionМоя задача сделать так, чтобы на выбор и-того элемент одного списка выбирался и-тый элемент...