Vue request can't get component data - vue.js

I am trying to disable loading when the HTTP request returns an error, but it gives me this error.
Uncaught (in promise) TypeError: Cannot set property 'loading' of undefined
Code
export default {
name: 'login',
data() {
return {
loading: false, //can't be set to false on request error
}
},
methods: {
login: function () {
this.loading = true;
const { username, password } = this
this.$store.dispatch('login', { username, password }).then((resp) => {
setTimeout(() => {
this.loading = false;
}, 5000);
// this.$router.push({name: 'dashboard'})
}).catch(function (error) {
this.loading = false; // Uncaught (in promise) TypeError: Cannot set property 'loading' of undefined
console.log('error', error);
});
}
}
}
Any idea?

this represent to the object that called the function in catch method, not to the current vue component.
so either you can use var vm=this outside and use after like below.
login: function () {
this.loading = true;
var vm = this;
.....
.....
}).catch(function (error) {
vm.loading = false;
console.log('error', error);
});
}
Or use arrow method
login: function () {
.....
.....
}).catch((error) => {
this.loading = false;
console.log('error', error);
});
}
You already used arrow method with setTimeout in below code, so I guess you aware of this, just use this to fix this also
setTimeout(() => {
this.loading = false;
}, 5000);

Related

Why is InterstitialAd not loaded after the first trigger?

I manage to get the first ad to show, but app crashed the next time I try to trigger an ad. And gives me this error: Error: InterstitialAd.show() The requested InterstitialAd has not loaded and could not be shown
In App.js
componentDidMount() {
const eventListener = interstitial.onAdEvent(type => {
if (type === AdEventType.LOADED) {
this.setState({
setLoaded: true,
});
}
});
interstitial.load();
eventListener();
}
showAds = () => {
interstitial.show();
// No advert ready to show yet
if (!this.state.loaded) {
console.log('null');
return null;
}
};
// This trigger is within another function
this.showAds();
I have a class component so I use ComponentDidMount instead of useEffect. Might that cause some troubles?
UPDATE:
this.state = {
loaded: false,
setLoaded: false,
Listener: null,
};
The above state is an attempt to redo
const [loaded, setLoaded] = useState(false);
constructor () {
super();
this.Listener=null
}
componentDidMount() {
this.Listener = interstitial.onAdEvent(type => {
if (type === AdEventType.LOADED) {
this.setState({
loaded: true,
});
}else if(type === AdEventType.CLOSED){
this.loadAd()
}
});
this.loadAd()
}
componentWillUnmount(){
if(this.Listener!==null){
this.Listener()
}
}
loadAd = () =>{
this.setState({
loaded: false,
});
interstitial.load();
}
showAds = () => {
if (!this.state.loaded) {
console.log('null');
return null;
}else{
interstitial.show();
}
};

Nuxt fetch hook api can't access the api folder

I have an api that I call in my fetch() hook:
pages/pageOne.vue:
async fetch() {
const { store, error } = this.$nuxt.context;
try {
await store.dispatch("folderOne/apiOne", null, { root: true });
} catch (e) {
error({
message: "error"
});
}
}
then in my store I have apiOne action setup like this:
store/folderOne/index.js:
//importing the api file here
const actions = {
apiOne({ commit }) {
apiFile.apiOne().then(data => {
if(data && data.status === 200){
// then commit
}
})
.catch(error => {
console.log(error);
});
},
}
Then I have a file for my APIs setup like this:
api/apiFile.js:
import axios from "axios";
const httpClient = axios.create({
headers: {
key: 'value
}
});
const baseUrl = process.env.config.baseUrl;
export default {
apiOne() {
return httpClient.get(`${baseUrl}values);
},
}
It doesn't work. But when I call the same apiOne in a #click method it works. Anyone knows what's is wrong and how can I fix it?
your store is and should be a global construct of your application.
it means when you call for a action and your setup is correct, you don't have to handle directives/folders by yourself.
in your case all you should do is dispatch the action in your component like this:
async fetch() {
const { store, error } = this.$nuxt.context;
try {
await store.dispatch("apiOne", null, { root: true });
} catch (e) {
error({
message: "error"
});
}
}

vue updating data on create()

I am trying to update an array from my view data() inside my created hook() but my console says that the allFish is undefined. I'm not so great with vue data scoping yet and I was hoping someone could let me know if this is a diction issue, or if there's a better way to update my data on create() when receiving data from a get request and then adding it to an array inside my data.
my current app.vue
export default {
name: "App",
components: {
WebMap
},
data: () => ({
coords: {
latitude: -118,
longitude: 34,
},
date: '',
fishType: '',
allFish: []
}),
created(){
this.allFish = this.fetchFishLocations()
},
methods: {
fetchFishLocations(){
axios.get('http://localhost:3000/allFish')
.then(function (response) {
// handle success
console.log(response.data.fish);
return response.data.fish
})
.catch(function (error) {
// handle error
console.log(error);
})
},
async updateCenter() {
console.log(this.allFish) //check to see if allFish is defined
await this.getLocation();
this.addFishToDb()
},
},
};
The function which is called fetchFishLocations just returns undefined.
You'd better learn about the use of promise.
By the way, it's easier to use the arrow function
// solution 1
created(){
this.fetchFishLocations()
},
methods: {
fetchFishLocations(){
const that = this
axios.get('http://localhost:3000/allFish')
.then(function (response) {
// handle success
console.log(response.data.fish);
that.allFish = response.data.fish
})
.catch(function (error) {
// handle error
console.log(error);
})
}
}
// solution 2
created(){
const that = this
this.fetchFishLocations()
.then(function (response) {
// handle success
console.log(response.data.fish);
that.allFish = response.data.fish
})
.catch(function (error) {
// handle error
console.log(error);
})
},
methods: {
fetchFishLocations(){
return axios.get('http://localhost:3000/allFish')
}
}
You need fill allFish in axios->then method.
...
created() {
this.fetchFishLocations();
},
methods: {
fetchFishLocations(){
axios.get('http://localhost:3000/allFish')
.then(function (response) {
// handle success
console.log(response.data.fish);
this.allFish = response.data.fish;
})
.catch(function (error) {
// handle error
console.log(error);
})
},
}
...

How can I return error message from axios function inside Vuex action to dispatch catch(error)?

I have an action where ajax call is made using axios,whenever the axios returns errors it gets catch by axios catch function , so i want to know if its possible to throw that same error to dispatch catch function.
I've tried to //throw new Error("test error inside"); from inside of axios catch(error) but dispatch doesnot seem to catch the error
Action code on vuex store
actions:{
assignOrder(context, assign){
axios.post('/assignOrder',assign)
.then((response) => {
console.log(response)
})
.catch((error) => {
//I want to throw error catched from here
console.log(error.response.data.errors)
//throw new Error("test error inside");
// }
})
}
}
On my method on vue component
methods:{
setAssign(){
this.assign.order_id = this.order.id
if(this.validate()){
this.errors = {};
this.$store.dispatch('assignOrder', this.assign).then(() => {
showNotify('success','Order has been assigned')
this.$store.dispatch('getOrders',this.active)
})
.catch((error) => {
//catch the error here
alert(error)
})
}
else{
this.showErr = true;
}
},
}
I want the axios to throw catch error which will catch by dispatch
Just return a promise from your action then handle that on your component :
actions: {
assignOrder(context, assign) {
return new Promise((resolve, reject) => {
axios.post('/assignOrder', assign)
.then((response) => {
resolve(response)
})
.catch((error) => {
reject(error.response.data.errors)
})
})
}
}
and on your component :
methods: {
setAssign() {
this.assign.order_id = this.order.id
if (this.validate()) {
this.errors = {};
this.$store.dispatch('assignOrder', this.assign).then((res) => {
showNotify('success', 'Order has been assigned')
console.log(res)
this.$store.dispatch('getOrders', this.active)
})
.catch((error) => {
// catch the error
alert(error)
})
} else {
this.showErr = true;
}
},
}
The promise will return either a resolve or a reject which will be bound to your then or catch
You can just return Promise in action and handle the response/error in method
vuex store:
actions:{
assignOrder(context, assign){
return axios.post('/assignOrder',assign)
}
}
and in your component do the following:
methods:{
setAssign() {
this.assign.order_id = this.order.id
if (this.validate()) {
this.errors = {};
this.$store.dispatch('assignOrder', this.assign).then(() => {
showNotify('success','Order has been assigned')
this.$store.dispatch('getOrders', this.active)
}).catch((error) => {
//catch the error here
alert(error)
})
} else{
this.showErr = true;
}
},
}

how to reference itself in a component in vuejs single file component

So here is my code:
export default {
data(){
return {
list: {}
}
},
components: {
listFields : ListFields
},
methods : {
submitForm(data){
let vm = this;
console.log(vm);
axios.post('/api/dashboard/lists/create', data)
.then(function (response) {
this.$router.push({path: 'show-list', params: {list_id: response.data.id}});
}).catch(function (error) {
console.log(error);
})
}
}
}
the problem is that inside the method where I am calling "this.$router.push" it throws an error, because this references to the function. But the problem is that I can't reference vm, because I am exporting the component. How can I solve this problem?
Your callback function is not aware of the outer context.
Either use .bind(this) or declare var that = this;
axios.post('/api/dashboard/lists/create', data)
.then(function (response) {
this.$router.push({path: 'show-list', params: {list_id: response.data.id}});
}.bind(this)).catch(function (error) {
console.log(error);
})
or
var that = this;
axios.post('/api/dashboard/lists/create', data)
.then(function (response) {
that.$router.push({path: 'show-list', params: {list_id: response.data.id}});
}).catch(function (error) {
console.log(error);
})
Update:
Since somehow nothing seems to work you can try the following: Declare a seperate method for the callback
methods : {
submitForm(data){
axios.post('/api/dashboard/lists/create', data)
.then(this.onSuccess)
.catch(function (error) {
console.log(error);
})
},
onSuccess(response) {
this.$router.push({path: 'show-list', params: {list_id: response.data.id}});
}
}