-1

I'm just learning Javascript/API call & I'm having trouble with fetch. When I call the fetch function from myFunction it doesn't do anything (that I can see), but if I take it out of myFunction it will display the error message that I expect.

I've tried to Google this but I haven't found anything that has helped me. I've added the console.log statements to make sure that the function is being called, and it is.

I've tried taking the fetch statement out of the function, and instead just putting it as a script in the html file. It works fine then. However I want to call it using the function name of a function that's in a javascript file & I'd like to understand why it's not working correctly right now. I think it has something to do with fetch not returning before the function exits, but I'm not sure.

javascript function:

function myFunction(){


    fetch('https://sickw.com/api.php?format=html&key=SOME_KEY&imei=12908438754328705&service=999999')
      .then(response => response.text())
      .then(data => {
        //document.write(data)
        console.log(data)
      });

    //make sure the function was called
    console.log("hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
}

html code:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  <title>Ghibli App</title>

  <link href="https://fonts.googleapis.com/css?family=Dosis:400,700" rel="stylesheet" />
  <link href="style.css" rel="stylesheet" />
</head>

<body>
  <div id="root"></div>

  <form>
    <select id="carrier">
      <option value="carrier">Carrier</option>
      <option value="icloud">iCloud</option>
    </select>
    <button onClick="myFunction('carrier');">Submit</button>"
  </form>

  <script src="scripts.js"></script>
</body>

</html>

I'm expecting to get a page to come up that says "Error S01: Service ID is wrong!" however the page isn't changing at all when I call the code from myFunction().

Félix Gagnon-Grenier
  • 7,344
  • 10
  • 45
  • 58

1 Answers1

2

Why you don't see anything:

The problem isn't that you're calling fetch from within a function, but that you're calling that function within the onclick of a button in a form.

When you place a <button> element inside of a <form> element, its default behavior is to submit the form (posting the results to a different web page and loading that new page in the browser). Since your form doesn't have an action attribute, it will just reload the current page. This reloading of the current page is causing you to not see any results.

Fixing the first issue:

To prevent the form from returning, you need to call preventDefault() on the event passed to your function:

function myFunction(event){
    event.preventDefault();

    fetch('https://sickw.com/api.php?format=html&key=SOME_KEY&imei=12908438754328705&service=999999')
      .then(response => response.text())
      .then(data => {
        //document.write(data)
        console.log(data)
      });

    //make sure the function was called
    console.log("hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
}

The second issue

However because of the way you're calling this function (passing it to the onclick method of an HTML element) you don't have access to that event. To rectify this, you should use the addEventListener method like so:

document.getElementsByTagName("button")[0].addEventListener("click", myFunction);

If you give the button an ID, this can be replaced with:

document.getElementById("button-id").addEventListener(...)

The third issue

You're passing 'carrier' directly to your function, but my guess is that you want to read the value from the <select> element. To do this, you should use document.getElementById and .value to read the select:

var carrier = document.getElementById("carrier").value;

Once you've done that, you can utilize carrier in your fetch request

The fourth issue

As others have already mentioned in the comments, you should avoid calls to document.write. There are books written about why it's bad, but the proper answer is to use the DOM API to modify elements on the page. For instance:

var p = document.createElement("p");
p.innerHTML = data;
document.appendChild(p);

The final code

index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  <title>Ghibli App</title>

  <link href="https://fonts.googleapis.com/css?family=Dosis:400,700" rel="stylesheet" />
  <link href="style.css" rel="stylesheet" />
</head>

<body>
  <div id="root"></div>

  <form>
    <select id="carrier">
      <option value="carrier">Carrier</option>
      <option value="icloud">iCloud</option>
    </select>
    <button id="button-id">Submit</button>"
  </form>

  <script src="scripts.js"></script>
</body>

</html>

script.js

function myFunction(event){
    event.preventDefault();
    var carrier = document.getElementById("carrier").value;
    fetch('https://sickw.com/api.php?format=html&key=SOME_KEY&imei=12908438754328705&service=999999&carrier=' + carrier)
      .then(response => response.text())
      .then(data => {
          var p = document.createElement("p");
          p.innerHTML = data;
          document.appendChild(p);
      });
}

document.getElementById("button-id").addEventListener("click", myFunction);
stevendesu
  • 13,153
  • 13
  • 76
  • 146
  • Thank you for your help! For issue #2 are you saying that I should use `addEventListener` instead of `onClick` so that I can access the event? – Sam Ventocilla May 15 '19 at 18:56
  • @SamVentocilla That's exactly right. Instead of using the `onclick` HTML attribute, if you use the `addEventListener` JavaScript method then your function will automatically be called with the event as its first parameter, which you can use prevent the event's default behavior (submitting the form). I would need to test it to be sure, but I ***think*** as a work-around you can use the HTML `onclick` attribute and have your function return `false`. In either case, using `addEventListener` is considered better practice since it keeps your code separate from your view. – stevendesu May 15 '19 at 18:59