IP Address tracker with Google Map and IP Geolocation API

Solution retrospective
I got API from google map but there is 1 issue with the search function. When search, even though the click event has been fire from the first click, but the map only load on the second click. I searched through various forum but cannot identify the cause of this. It would be helpful to know what causing this issue. Thank you.
Please log in to post a comment
Log in with GitHubCommunity feedback
- @pikapikamart
Hey great work you got there. Regarding your query, I looked into your js and this is my conclusion.
But first suggestion in js. Your event listener in the button for entering, you may want to preventDefault the event for it, since it is an a tag, we don't want the browser to refresh everytime we submit. Change it to this
submitButton.addEventListener('click', event => { event.preventDefault(); getData(); initMap(); });
Now for the question of yours. I havent used this map API. But it is asynchronous right, so it fetches first. Okay this is what happens in your js. When a user click right, the
getData()
function runs right, and theinitMap()
should run next, well, in this case it is not. Since inside of the function of yourgetData
is asynchronous, meaning it runs with everything realtime. So while this function is fetching data for the API, theinitMap
will start running, and it runs without a proper data. That is why, it works for the second time, because at that point, you just fetched the data that you need. To fix this.function getData(){ getIPGeo(input.value).then(data => { ipAdd.innerText = data.ip; geo.innerText = `${data.location.city}, ${data.location.country} ${data.location.postalCode}`; timezone.innerText = `UTC ${data.location.timezone}`; isp.innerText = data.isp; loc = { lat: data.location.lat, lng: data.location.lng }; contentString = `<h3>${data.ip}</h3><p>${data.location.city}, ${data.location.country} ${data.location.postalCode}</p>`; }); }
This is the
getData
function of yours, what you should do, is continue to pipe the data, and run only theinitMap
after we get the data. This should look like this.function getData(){ getIPGeo(input.value).then(data => { ipAdd.innerText = data.ip; geo.innerText = `${data.location.city}, ${data.location.country} ${data.location.postalCode}`; timezone.innerText = `UTC ${data.location.timezone}`; isp.innerText = data.isp; loc = { lat: data.location.lat, lng: data.location.lng }; contentString = `<h3>${data.ip}</h3><p>${data.location.city}, ${data.location.country} ${data.location.postalCode}</p>`; }) .then( data => {initMap();}); }
See the addition of the another
then
method. This means after we run the first, pipe it, then run the next. This make sure you get the data properly before initializing the map apiHope this works properly and clarify thing^^
Join our Discord community
Join thousands of Frontend Mentor community members taking the challenges, sharing resources, helping each other, and chatting about all things front-end!
Join our Discord