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".





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


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.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Export result set on Dbeaver to CSV

Opening a url is failing in Swift