Cannot set property after Get reques - Axios and HTML5 datalist - vuejs2

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);
});
}

Related

Calling API in method and getting [object Promise]

I'm using Nuxt.js in static site mode, and trying to get an image from an API using a string passed in a prop, however, in the template I am getting [object Promise]. I would've thought that return before the get request would resolve the promise, but I think my grasp of promises and Nuxt.js a little off. Any help would be greatly appreciated.
<template>
<div>
{{ getThumbnailSrc() }}
</div>
</template>
<script>
import axios from 'axios'
export default {
props: {
link: {
type: String,
required: true
}
},
data() {
return {
imageUrl: null
}
},
methods: {
getVimeoId(link) {
return link.split('/').pop()
},
getThumbnailSrc() {
return axios
.get(
`https://vimeo.com/api/v2/video/${this.getVimeoId(
this.link
)}.json`
)
.then(response => {
const vimeoThumbnailUrl = response.data[0].thumbnail_large
console.log(vimeoThumbnailUrl)
return {
vimeoThumbnailUrl
}
})
.catch(error => {
console.log(error)
})
}
}
}
</script>
It sure won't! XHR requests are asynchronous and therefore the template has no idea that it needs to wait.
Solve it by using an additional data property on the component, and using that instead:
data() {
return {
imageUrl: null,
thumbnailSrc: null
}
},
And in your callback:
.then(response => {
const vimeoThumbnailUrl = response.data[0].thumbnail_large
console.log(vimeoThumbnailUrl)
this.thumbnailSrc = vimeoThumbnailUrl
})
Now you can use {{thumbnailSrc}} and it will load appropriately.

Nuxt.js and handle API 404 response for dynamic pages

I use Nuxt.js and I have dynamic page /items/{id}:
<template>
<div>
<h1>Item #{{ item.id }} «{{ item.title }}»</h1>
</div>
</template>
<script>
import { api } from '../../mo/api'
export default {
asyncData({ params }) {
return api(`items/${params.id}`)
},
}
</script>
Backend API returns object {item: {id: .., title: "...", ...}}.
But if an item with specified ID not exist API returns 404 response.
And Vue crash with "[Vue warn]: Property or method "item" is not defined on the instance but referenced during render."
How can I handle 404 response?
My api.js module:
import axios from 'axios'
export function api(url) {
url = encodeURIComponent(url)
return axios
.get(`http://localhost:4444/?url=${url}`)
.then(({ data }) => {
return data
})
.catch((err) => {
// 404 catch there
})
}
Solution:
Need to read manual: https://nuxtjs.org/guide/async-data/#handling-errors
just execute error function :)
<script>
export default {
asyncData({ params, error }) {
return axios
.get(`https://my-api/posts/${params.id}`)
.then((res) => {
return { title: res.data.title }
})
.catch((e) => {
error({ statusCode: 404, message: 'Post not found' })
})
},
}
</script>
If you're using the fetch() hook, this is how it should be written
<script>
export default {
async fetch() {
try {
await fetch('https://non-existent-website.commmm')
.then((response) => response.json())
} catch (error) {
this.$nuxt.context.error({
status: 500,
message: 'Something bad happened',
})
}
},
}
</script>
More context available here: https://nuxtjs.org/announcements/understanding-how-fetch-works-in-nuxt-2-12/#error-handling
Need to read the manual: https://nuxtjs.org/guide/async-data/#handling-errors :) .

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);
});
}
}

Printing data variable

I am trying to print data() variable. I am not getting output in HTML template.
<template>
<h3>{{app_skills}}</h3> <!-- I am not getting value here -->
</template>
<script>
export default {
name: "leftbar",
data() {
return {
app_skills: '',
}
},
methods : {
fetchskills (url) {
url = '/skills';
axios.get(url)
.then(response => {
this.app_skills = response.data.skills;
console.log(this.app_skills) // I am getting value here
})
.catch(error => {
console.log(error);
});
}
},
mounted() {
this.fetchskills();
}
}
</script>
Your code worked exactly as expected when I tried it (with a few environment-related changes):
<template>
<h3>{{app_skills}}</h3> <!-- I am not getting value here -->
</template>
<script>
import axios from 'axios';
export default {
name: "leftbar",
data() {
return {
app_skills: '',
}
},
methods : {
fetchskills (url) {
url = 'https://dns.google.com/resolve?name=example.com';
axios.get(url)
.then(response => {
this.app_skills = response.data;
console.log(this.app_skills) // I am getting value here
})
.catch(error => {
console.log(error);
});
}
},
mounted() {
this.fetchskills();
}
}
</script>
All I changed was including the axios library, changing the URL to pull from, and changing the response.data key to pull. It all works as expected. Perhaps you have an issue somewhere else in your surrounding code?

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);
});
}