Build axios url with vue data - getting undefined
Build axios url with vue data - getting undefined
I'm trying to use axios to get data from openweathermap, currently, I'm building the url by using a few methods to get the lat and lon from the user browser and then call a function that builds the url.
The url is built properly and without any issues, but when I try to call the api with axios, weird stuff happens (basically I'm getting my own page html code returned to me)
Here is the code:
let weather = new Vue ({
el: '#weather',
data: {
error: '',
apiUrl: '',
city: '',
country: '',
icon: '',
description: '',
results: ,
},
methods: {
getPosition: function() {
if (navigator.geolocation){
navigator.geolocation.getCurrentPosition(this.getUrl);
}else{
this.error = 'Geolocation is not supported.';
}
},
getUrl: function(position){
let lat = position.coords.latitude;
let lon = position.coords.longitude;
this.apiUrl = buildWeatherUrl(lat, lon);
},
getWeather: function(){
axios.get(this.apiUrl).then(function (response) {
this.city = response.data.name;
this.results = response.data;
}).catch( error => { console.log(error); });
}
},
beforeMount() {
this.getPosition();
},
mounted() {
this.getWeather();
}
});
This is my the first time using Vue and axios so I'm not sure what I'm doing wrong here. I also tried to add let self = this;
and replace all this
to self
in the getWeather
function but that didn't work.
let self = this;
this
self
getWeather
The issue is that I'm trying to get the url from apiUrl
which should get updated by the getUrl
method. Although when getWeather
is ran after mounted the url doesn't seem to be updated (if its hardcoded it works fine).
apiUrl
getUrl
getWeather
Thank you for the help.
3 Answers
3
I suspect the problem is this line navigator.geolocation.getCurrentPosition(this.getUrl);
.
navigator.geolocation.getCurrentPosition(this.getUrl);
When this.getUrl
is called back by the navigator
, the function no longer has the correct this
, therefore this.apiUrl = buildWeatherUrl(lat, lon);
will not work. Try binding this
to this.getUrl
, like so
this.getUrl
navigator
this
this.apiUrl = buildWeatherUrl(lat, lon);
this
this.getUrl
getPosition: function() {
if (navigator.geolocation){
let getUrl = this.getUrl.bind(this)
navigator.geolocation.getCurrentPosition(getUrl);
}else{
this.error = 'Geolocation is not supported.';
}
},
Or simply navigator.geolocation.getCurrentPosition(this.getUrl.bind(this));
navigator.geolocation.getCurrentPosition(this.getUrl.bind(this));
This function also has an incorrect this
.
this
axios.get(this.apiUrl).then(function (response) {
this.city = response.data.name;
this.results = response.data;
}).catch( error => { console.log(error); });
You'll either need to redo your previous fix:
I also tried to add let self = this; and replace all this to self in
the getWeather function but that didn't work.
Or simply use an arrow function.
axios.get(this.apiUrl).then(response => {
this.city = response.data.name;
this.results = response.data;
}).catch( error => { console.log(error); });
Here's a link to the definitive stack overflow answer about how to manage Javascript's this
: https://stackoverflow.com/a/20279485/2498782
this
Scroll to the answer's section labeled "Common problem: Using object methods as callbacks/event handlers".
response.data
I guess you registered the route as a POST
request and not a GET
request in the routes file. Just change it to GET
and code will be fixed.
POST
GET
GET
This isn't the case as I am just working with a single js file where I am calling a vue instance
– FabioRosado
2 days ago
can you console.log(this.apiUrl) and share the result?
– Toney Dias
2 days ago
In your case, the url inside the axios.get(this.apiUrl) is not a legitimate url or is returning some kind of junk value as response.
– Toney Dias
2 days ago
I'm using my api key there but basically, its something like:
"http://api.openweathermap.org/data/2.5/weather?units=metric&lat=51.2514596563852&lon=-0.1661086240457241&APPID={{apikey}}
– FabioRosado
2 days ago
"http://api.openweathermap.org/data/2.5/weather?units=metric&lat=51.2514596563852&lon=-0.1661086240457241&APPID={{apikey}}
I probably did something silly since I tried to comment out all the Vue. Created a data object, built the url and added it to the data object. When I console log the object the data shows empty but when I open it from the console the url is there. There must be some issue with my logic I guess
– FabioRosado
2 days ago
I was able to fix this issue by commenting out all the vue code, then create an empty object called data and try to put the api url in that object. After failing constantly I realised that the url couldn't be passed to the object from within navigator.geolocation.getCurrentPosition
so I played with global variables and something hit me, the issue was in how I was trying to get the url from within navigator.geolocation.getCurrentPosition
navigator.geolocation.getCurrentPosition
navigator.geolocation.getCurrentPosition
So I fixed the issue by adding lat
and lon
to data in the vue and then build the url before calling axios. That gave me the right results.
lat
lon
Here is the final code in case it's useful for someone.
let weather = new Vue ({
el: '#weather',
data: {
error: '',
lat: 0,
lon: 0,
apiUrl: '',
city: '',
country: '',
icon: '',
description: '',
results: ,
},
methods: {
getPosition: function() {
if (navigator.geolocation){
var vm = this;
navigator.geolocation.getCurrentPosition(this.updatePosition);
}else{
this.error = 'Geolocation is not supported.';
}
},
updatePosition: function(position) {
this.lat = position.coords.latitude;
this.lon = position.coords.longitude;
},
getWeather: function(){
let url = buildWeatherUrl(this.lat, this.lon);
axios
.get(url)
.catch(function (error) {
console.log(error);
})
.then(function (response) {
console.log(response.data);
});
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Thank you so much for your help Eric, unfortunately, axios is still returning my own html code on
response.data
. I also didn't have any issues with the getPosition function before but I have added your suggestion to see if that would fix it, unfortunately it didn't– FabioRosado
2 days ago