How to handle the axios errors in the context of Vuejs - api

I want to display/print 'Disabled' when ever my API returns any error and display 'Enabled' when it is returning successfully with 200 ok status.
Here's what my API is returning:
So, my API is returning error currently, so i want to print/display 'Disabled'.
Here how i did it:
<template>
<div class="api_data">
<span class="trick_not_ok" v-if="error" >{{error}}</span>
<span class="trick_ok" v-if="noerror" >{{noerror}}</span>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: Api_data,
data () {
return {
error: [],
noerror: []
}
},
created() {
axios.get('...URL...')
.then((response) => {
console.log(response.data)
this.noerror = 'Enabled'
})
.catch((error) => {
if (error) {
console.log(error)
this.error = 'Disabled'
}
})
}
}
</script>
But nothing is printed/displayed on my screen, and i am getting error in my console as GET ...URL... 401 (UNAUTHORIZED), How do i display 'Disabled' when my API returns error and 'Enabled' when my API is returning successfully.
Note: I have also tried in .catch as if (error.response.stastus) and if (error.status) but both did not work and i am getting the same error in my console.
Someone please do help me with this.

Here
is a codepen solution that I'd use for your trouble. Using boolean for selecting the status and then string for the message you want to display.
new Vue({
el: "#app",
data () {
return {
isError: false,
noerror: false,
message:'loading'
}
},
created() {
axios.get('...URL...')
.then((response) => {
console.log(response.data)
this.noerror = true
this.message = 'enabled'
})
.catch((error) => {
if (error) {
console.log(error)
this.isError = true
this.message = 'disabled'
}
})
},
methods: {
toggle: function(todo){
todo.done = !todo.done
}
}
})
<div id="app">
<div class="api_data">
<span class="trick_not_ok" v-if="isError">{{message}}</span>
<span class="trick_ok" v-if="noerror">{{message}}</span>
</div>
</div>

you need to the code to understand what this status is,
switch(status) { case 401: message = 'UNAUTHORIZED'; break ...}
or from api you send a json for error message and return by error.response.data.message for this json:
{"message": "UNAUTHORIZED"}

Your code seems ok. Here is the working demo.
new Vue({
el: "#api_data",
data() {
return {
error: null,
noerror: null
}
},
mounted() {
axios.get('https://api.bonsai.io/clusters')
.then((response) => {
console.log(response.data)
this.noerror = 'Enabled'
})
.catch((error) => {
if (error) {
this.error = 'Disabled'
}
})
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script>
<div id="api_data">
<span class="trick_not_ok" v-if="error">{{error}}</span>
<span class="trick_ok" v-if="noerror">{{noerror}}</span>
</div>

Related

Vue.js Composition API vs Options API - posts ref in a v-for loop

I'm still new to VueJS, and I cannot figure this one out.
I have a page that loads with axios from wordpress my posts:
export default {
data() {
return {
postsUrl: "https://localhost/wordpress/wp-json/wp/v2/news",
posts: [] as any[],
isLoading: false,
regex: /(<([^>]+)>)/gi,
errorCaught: false,
};
},
methods: {
getPosts() {
this.isLoading = true;
axios
.get(this.postsUrl, { params: { _embed: true } })
.then((response) => {
this.posts = response.data;
console.log("Pages retrieved!");
console.log(this.posts);
this.isLoading = false;
})
.catch((error) => {
console.log(error);
if (error) {
this.isLoading = false;
setTimeout(() => {
this.errorCaught = true;
}, 1100);
}
});
},
},
mounted() {
this.getPosts();
},
};
and the template
<template>
<div class="news-container">
<div class="loading">
<transition name="fadeLoading">
<div v-if="isLoading">Loading...</div>
</transition>
<transition name="fadeLoading">
<div v-if="errorCaught">There was an error loading news</div>
</transition>
</div>
<ul v-for="(index) in posts" :key="index" ref="posts">
<h1>
<router-link :to="index.slug" tag="div" key="page.id"
>{{ index.title.rendered }}
</router-link>
</h1>
<img
v-if="index._embedded['wp:featuredmedia']"
:src="index._embedded['wp:featuredmedia'][0].source_url"
/>
<p class="date">{{ index.date }}</p>
</ul>
</div>
</template>
This works fine, no problem with the Options API.
But when I want to convert this to the Composition API, the posts don't appear:
<script setup lang="ts">
import axios from "axios";
import { ref } from "vue";
import { onMounted } from "vue";
const postsUrl = "https://localhost/wordpress/wp-json/wp/v2/news";
var posts = ref([] as any);
const isLoading = ref(false);
const regex = /(<([^>]+)>)/gi;
const errorCaught = ref(false);
const getPosts = () => {
isLoading.value = true;
axios
.get(postsUrl, { params: { _embed: true, page: 1 } })
.then((response) => {
posts = response.data;
console.log("Pages retrieved!");
console.log(posts);
isLoading.value = false;
})
.catch((error) => {
console.log(error);
if (error) {
errorCaught.value = true;
}
});
};
onMounted(() => {
getPosts();
});
</script>
I suspect there is a misunderstanding on my part how refs work, because If I edit the <template> (and have npm run dev running the server), I can see that the posts appear.
Could you help me with what am I doing wrong and why?
Thank you for your time
Your mistake is here
posts = response.data;
When you use ref you have to use it with value. Change your code to this:
posts.value = response.data;
It should be working fine. For more detail you should check here:
https://vuejs.org/api/reactivity-core.html#ref

How to fix TypeError in vue.js created hook?

error:
vue.js:597 [Vue warn]: Error in created hook: "TypeError: handlers[i].call is not a function"
found in
---> <StageExecs>
vue.js
<div id="vue-job">
<div class="row">
<h3>test</h3>
<stage-execs></stage-execs>
</div>
</div>
<script>
Vue.component('jobs', {
delimiters: [ '[[', ']]' ],
props: ['job'],
data: function() {
return {
showExecs: false,
build_ids: []
}
},
created: {
stageExecs() {
url = "api/v2/exec?" + this.job.api_url + "&limit=10"
fetch(url)
.then(response => response.json())
.then(body => {
for(i=0; i<body.length; i++){
this.build_ids.push({
'id': JSON.stringify(body[i].build_id),
})
}
})
.catch( err => {
console.log('Error Fetching:', url, err);
return { 'failure': url, 'reason': err };
});
}
},
template: `
<ul id="example-1">
<li v-for="item in build_ids">
[[ item.url ]]
</li>
</ul>
`,
});
var v_root = new Vue({
delimiters: [ '[[', ']]' ],
el: '#vue-job',
data: {
job_exec: {{ job_exec|safe }},
}
});
I assume something is being called in the incorrect order here, but new to vue.js so not sure what I did wrong.
The problem is created() hook needs to be a method, not an object. See this working sandbox fix https://codesandbox.io/s/vue-template-e0dzj
created() {
url = "api/v2/exec?" + this.job.api_url + "&limit=10"
fetch(url)
.then(response => response.json())
.then(body => {
for(i=0; i<body.length; i++){
this.build_ids.push({
'id': JSON.stringify(body[i].build_id),
})
}
})
.catch( err => {
console.log('Error Fetching:', url, err);
return { 'failure': url, 'reason': err };
});
}
},
your data component should be an object, not a function, you replace it like below :
please check the doc as well : Declarative-Rendering
data: {
return {
showExecs: false,
build_ids: []
}

Cannot set property after Get reques - Axios and HTML5 datalist

I am trying to do a GET request using Axios , but get the following error in console:
TypeError: Cannot set property 'films' of undefined
at eval (SearchBar.vue?e266:26)
SearchBar.vue
<template>
<section>
<input v-model='film' type='text' list='films'>
<datalist id='films'>
<option v-for='film in films' :key='film.episode_id'>{{film}}</option>
</datalist>
</section>
</template>
<script>
import axios from "axios";
export default {
name: "SearchBar",
data() {
return {
film: "",
films: []
};
},
created() {
axios
.get("https://swapi.co/api/films/")
.then(function(response) {
// handle success
//console.log(response);
this.films = response.data.results;
})
.catch(function(error) {
// handle error
console.log(error);
});
}
};
</script>
Anyone can tell me why I get the error? Note: I am running this locally for instant prototyping via Vue-Cli
One way is to use Arrow function:
created() {
axios
.get("https://swapi.co/api/films/")
.then((response) => {
// handle success
//console.log(response);
this.films = response.data.results;
})
.catch(function(error) {
// handle error
console.log(error);
});
}
2. Another way that = this & then use that inside promise callback
created() {
const that = this; // <-- assign this in that
axios
.get("https://swapi.co/api/films/")
.then(function (response) {
// handle success
//console.log(response);
that.films = response.data.results;
})
.catch(function(error) {
// handle error
console.log(error);
});
}

axios typeError: Cannot set property 'username' of undefined

When I used POSTMAN to test the backend API, everything went right and the response data looked like:
{"username":"123","email":"123#gmail.com"}. Then I used axios to get the data:
<template>
<div>
<h1>Welcome!</h1>
<div>
<b-button #click="getInfo()">Get your information</b-button>
<h2 v-if="username !== ''">Your username is: {{ username }}</h2>
<h2 v-if="email !== ''">Your email is: {{ email }}</h2>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data () {
return {
username: '',
email: ''
}
},
methods: {
getInfo () {
axios.get('http://localhost:8088/api/information')
.then(function (response) {
this.username = response.data['username'];
this.email = response.data['email'];
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
}
}
</script>
But there was an error typeError: Cannot set property 'username' of undefined. I am confused about it. Could anyone help?
you should use the arrow function in es6 instead of function () in here,
example: (response)=>{ instead of function(response){
methods: {
getInfo () {
axios.get('http://localhost:8088/api/information')
.then((response)=> {
this.username = response.data['username'];
this.email = response.data['email'];
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
}

Vue.js props not showing actual message value, What have I done and how can I solve it?

I am learning vue.js and for my practice purpuse I am making an chatting app. in my chatlog component I used props. when I print those property in console it's ok and print all the object in console but in templete they all are vanished. My code is bellow.
Thanks in advance.
Chatlog
<template>
<div class="chat-log">
<button #click="showOnConsole">Show on console</button>
<p>{{ messages}}</p>
</div>
</template>
<script>
export default {
props: ['messages'],
methods: {
showOnConsole()
{
console.log(messages);
}
}
}
</script>
app.js
const app = new Vue({
el: '#app',
data:{
messages: []
},
created: function() {
axios.get('/Chat/public/messages')
.then(function (response) {
this.messages = response.data;
})
.catch(function (error) {
console.log(error);
});
}
});
Rewrite your created method, so you bind your own this:
created: function() {
axios.get('/Chat/public/messages')
.then(response => {
this.messages = response.data;
})
.catch(function (error) {
console.log(error);
});
}
Or without using an arrow function:
created: function() {
var that = this
axios.get('/Chat/public/messages')
.then(function (response) {
that.messages = response.data;
})
.catch(function (error) {
console.log(error);
});
}