0

I have the following functions for getting data from an API and setting the text of an HTML element by its ID:

var api_url = "https://api.wheretheiss.at/v1/satellites/25544";

var coordinates = {
    latitude : 0,
    longitude : 0
}

async function getISS() {
    const response = await fetch(api_url);
    const data = await response.json();
    const {latitude, longitude} = data;
    var spaceStationCoordinates = new coordinates({
        latitude: latitude,
        longitude: longitude
    });
    return spaceStationCoordinates;
}

async function setText(id,newvalue) {
    var s= document.getElementById(id);
    s.innerHTML = newvalue;
  } 

And then I use the functions to try and insert the latitude and longitude values in my HTML:

    <main>
      <h1>Where is the ISS?</h1>
      <p>Latitude: <span id="lat" type = text>""</span></p> <br>
      <p>Longitude: <span id="lon" type = text>""</span></p>
      <script src="js/script.js" type="text/javascript">
      var longitude = 0;
      var latitude = 0;
      latitude = getISS().latitude;
      longitude = getISS().longitude;
      setText(lat, latitude);
      setText(lon, longitude);
      </script> 
    </main> 

However this doesn't do anything at all. Any help is appreciated.

  • setText('#lat', latitude); Try to pass the ID like that. I think your passing a variable called lat to your function. And not the actual ID of the element. – MadeInDreams Nov 20 '20 at 03:11

4 Answers4

1

Pretty sure you need to await the response from your async functions

Try:

coordinates = await getISS();
setText(lat, coordinates.latitude);
setText(lon, coordinates.longitude);
LovingGarlic
  • 155
  • 1
  • 9
  • Thank you for that suggestion, but that unfortunately didn't work. I've changed the code to match yours as it is much prettier, but it didn't change the values. –  Nov 20 '20 at 03:11
0

The script tag in the html has a source: <script src="js/script.js" type="text/javascript">

So the browser notices that, and runs the code.
Then it assumes the script tag ended. (It run all the code from the source, right?)
So when it finds an "unexpected" character (v), it's interpreted as text.

    <main>
      <h1>Where is the ISS?</h1>
      <p>Latitude: <span id="lat" type = text>""</span></p> <br>
      <p>Longitude: <span id="lon" type = text>""</span></p>
      <script src="js/script.js" type="text/javascript">
        <!-- This is just some text, the script tag should be already finished -->
        var longitude = 0;
        var latitude = 0;
        latitude = getISS().latitude;
        longitude = getISS().longitude;
        setText(lat, latitude);
        setText(lon, longitude);
        </script> 
    </main>

What you need to do is either put all the inline code in your file, or put all the file code inline.

Like this:

var api_url = "https://api.wheretheiss.at/v1/satellites/25544";

var coordinates = {
    latitude : 0,
    longitude : 0
}

async function getISS() {
    const response = await fetch(api_url);
    const data = await response.json();
    const {latitude, longitude} = data;
    var spaceStationCoordinates = new coordinates({
        latitude: latitude,
        longitude: longitude
    });
    return spaceStationCoordinates;
}

async function setText(id,newvalue) {
    var s= document.getElementById(id);
    s.innerHTML = newvalue;
}

// inserted code
var longitude = 0;
var latitude = 0;
latitude = getISS().latitude;
longitude = getISS().longitude;
setText(lat, latitude);
setText(lon, longitude);

You can see that the browser thinks it's text:
Code not syntax highlighted shown as just text because it is.

Alto
  • 245
  • 4
  • 9
  • Thank you. This worked, but now I am getting the issue that the data I get back from getISS() is undefined. When I console.log the result of getISS() I get the following: Promise {[[PromiseState]]: 'pending', [[PromiseResult]]: undefined}. What do I do about that? As I understand it, I shouldn't have to use "then" when using async await. –  Nov 20 '20 at 04:24
  • @MongoosePainter I don't think you need an async function. By default the code waits for the function to finish. see very amazing: https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call. – Alto Nov 20 '20 at 21:40
0

getISS is a async function, you have call it as a async way (await keyword/ Promise style).

Promise style:

<main>
  <h1>Where is the ISS?</h1>
  <p>Latitude: <span id="lat" type=text>""</span></p> <br>
  <p>Longitude: <span id="lon" type=text>""</span></p>
  <script src="js/script.js" type="text/javascript">
    getISS().then(coordinates => {
      setText('lat', coordinates.latitude);
      setText('lon', coordinates.longitude);
    });
  </script>
</main>

async/await style, use IIFE

<main>
  <h1>Where is the ISS?</h1>
  <p>Latitude: <span id="lat" type=text>""</span></p> <br>
  <p>Longitude: <span id="lon" type=text>""</span></p>
  <script src="js/script.js" type="text/javascript">
    (async () => {
      const coordinates = await getISS(); // wait here
      setText('lat', coordinates.latitude);
      setText('lon', coordinates.longitude);
    })();
  </script>
</main>
hoangdv
  • 15,138
  • 4
  • 27
  • 48
0

This bug is separate so i'm submitting separate answers.


The new keyword requires a constructor.
Using it with an object will throw an error: new {exampleProperty: 7}(23)

    var spaceStationCoordinates = new coordinates({  // ERROR

So coordinates should be a constructor function or class:

var coordinates = {
    latitude : 0,
    longitude : 0
}

// INTO:
class coordinates {
    constructor (lat, lon) {
        this.latitude = lat;
        this.longitude = lon;
    }
}

// OR
function coordinates (lat, lon) {
    this.latitude = lat;
    this.longitude = lon;
}

Alto
  • 245
  • 4
  • 9