Anon
Anon

Reputation: 109

Ajax function only succeeds with "alert"

EDIT: My question is not a duplicate of No response from MediaWiki API using jQuery. Because even though it's a cross-domain request, I'm properly triggering JSONP behavior because jquery is automatically sending a callback parameter under the hood. (As you can see from the link I posted jQuery3100048749602337837095_1485851882249&_=1485851882253

EDIT2: Solved by @AnandMArora. Solution:

<input type="submit" onclick="getUserInput(event)" style="display:none"/>

and function

getUserInput(evt) { evt.preventDefault();

But since it's a comment I can't mark it as the answer. If there's an explanation why this method works (what is the default behavior that is prevented etc.) I will select it as the answer.

I assume that the "alert" method is buying time for the AJAX function since it's asynchronous. But I have no idea WHY do I need to buy time here. It should only be executed when getUserInput() calls getWiki() with the Input parameter. In fact, I looked at the network monitor and even if we remove alert("") the proper URL is called (assuming "batman" was submitted).

Request URL: https://en.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&generator=search&exsentences=1&exlimit=max&exintro=1&explaintext=1&exsectionformat=wiki&gsrnamespace=0&gsrsearch=batman&callback=jQuery3100048749602337837095_1485851882249&_=1485851882253

If I open this link manually, it works fine. But there's no status code returned and console logs "Error!"

function getUserInput(){
  var Input = document.getElementById("searchBox").value;
  getWiki(Input); 
  alert(""); //If we remove this line the request fails
}

function generatePage(rawData) {
  console.log(rawData);
  var mainData = rawData.query.pages;
  $.each(mainData, function(value){
    console.log((mainData[value].title + " " + mainData[value].extract));
  });

}


function getWiki(Input){
  $.ajax({
    url: "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&generator=search&exsentences=1&exlimit=max&exintro=1&explaintext=1&exsectionformat=wiki&gsrnamespace=0&gsrsearch=" + Input,
    dataType: "JSONP",
    type: "GET",
    success: function (rawData) {
      generatePage(rawData);
    },
    error: function() {
      console.log("Error!")
    }
  });
}


$(document).ready(function(){


})

The html I'm using to submit is:

<form class="searchForm">
      <input type="text" name="searchRequest" id="searchBox" >
      <input type="submit" onclick="getUserInput()" style="display:none"/>
      </input>
    </form>

My questions would be: 1) Why is this happening? 2) How can this be fixed without turning async off or using setTimeout() on the ajax function?

Upvotes: 3

Views: 112

Answers (3)

Anand M Arora
Anand M Arora

Reputation: 372

You are using ajax, and the input control type of "submit" has a default action of postback for the form in which it is placed. So jQuery and most javascript code use the evt.preventDefault(); // evt is the object of event passed as a parameter for the click event function this prevents the default action i.e. submit the form.

Please make the changes as :

<input type="submit" onclick="getUserInput(event)" style="display:none"/>

and

function getUserInput(evt) { evt.preventDefault(); ...

this will most probably be the solution.

Upvotes: 1

Alessandro
Alessandro

Reputation: 4472

1)You have to specify a callback function, don't put code directly (otherwise it will be executed) but put it in a function

error: function(){console.log("Error!");}

2)In order to wait for the response, you have to specify that your request it synchronous

Set async option to false

If you need an asynchronous solution please see the following snippets (using done method instead of success property):

<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.1.0.js"></script>
</head>
<body>
    <form class="searchForm">
      <input type="text" name="searchRequest" id="searchBox" >
      <input type="submit" onclick="javascript:getUserInput()" />
      </input>
    </form>
</body>
<script>
  function getUserInput(){
    var Input = document.getElementById("searchBox").value;
    getWiki(Input); 
    //alert(""); //If we remove this line the request fails
  }

function generatePage(rawData) {
  console.log(rawData);
  var mainData = rawData.query.pages;
  $.each(mainData, function(value){
    console.log((mainData[value].title + " " + mainData[value].extract));
      })

}


function getWiki(Input){
  $.ajax({
    url: "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&generator=search&exsentences=1&exlimit=max&exintro=1&explaintext=1&exsectionformat=wiki&gsrnamespace=0&gsrsearch=" + Input,
    dataType: "JSONP",
    type: "GET",
    async: true,
    error: function(){console.log("Error!");}

  }).done(
      function (rawData) {
        generatePage(rawData);
      }
  );
}


$(document).ready(function(){


})
</script>
</html>

I hope it helps you. Bye.

Upvotes: 0

Pineda
Pineda

Reputation: 7593

Wrap that console.log call inside a function:

function getWiki(Input){
  $.ajax({
    url: "https://en.wikipedia.org/w/api.php?action=query&format=json&prop=extracts&generator=search&exsentences=1&exlimit=max&exintro=1&explaintext=1&exsectionformat=wiki&gsrnamespace=0&gsrsearch=" + Input,
    datatype: "JSONP",
    type: "GET",
    success:
      function (rawData){
        generatePage(rawData);
      },
    error: 
      function(){
        console.log("Error!")
      }
  });
}

Explanation:

The ajax call expects functions definitions to be passed to its event handlers ('success'/'error' in this case).

You do this for the success handler. For your error handler you are not pushing a function definition but a function that you are actually invoking (the console.log method).

Wrapping it in a function declaration (like what you did for the success event callback) allows you to define what happens on the callback when it is invoked rather than invoked it in-line.

Upvotes: 2

Related Questions