DNorthrup DNorthrup - 1 month ago 5
PHP Question

Using data from AJAX Reply to a PHP Script (JSON)

Wording might be a bit off. I'm trying to use the Battle.NET API to retrieve some information regarding characters. I have a 'server' field, and a 'char name' field.

I've reviewed a few of the similar questions, like this one, and maybe it's just my PHP new-ness but I'm getting confused on how to properly do it. I'm still not sure at all how to troubleshoot PHP errors.

What I did was design the HTML + PHP embedded into one 'php' file. It Worked. I then separated them into index.html + test.php it worked
The main issue with that was a few things - I wasn't rendering the response, I JUST had it 'echo' the response. Which appears to have been in JSON

{"lastModified":1477156067000,"name":"Thischaracter","realm":"Thisrealm","battlegroup":"Thisbattlegroup","class":1,"race":6,"gender":0,"level":110,"achievementPoints":20805,"thumbnail":"thrall/50/129432626-avatar.jpg","calcClass":"Z","faction":1,"totalHonorableKills":8657}


So the flow needs to be HTML Form - Submit -> AJAX -> PHP form (This is far as my "experience" goes, because I've never done anything with the response) -> MAYBE a getJSON from the PHP data? -> HTML output. I mention AJAX because I don't want the page to update. Just a 'div' or LI to be updated.

index.html -- I modified this form a bit before posting here to remove extra non-sense.

<form action="testingApiForBnet.php" method="post" id="myForm">
<p class="inp-wrap search-wrap">
<label for="search-field" class="search-label grid-25">Find</label>
<input type="search" name="search-term" id="charSearch" class="grid-75"/></p>
<p class="inp-wrap cat-wrap">
<label for="categories" class="grid-20">on</label>
<select name="search categories" id="servers" class="grid-80">
</select>
</p>
<submit name="SubmitButton">
</form>


testAPI.php

<?php
if(isset($_POST['SubmitButton']))
{
$charName = $_POST['charName'];
##$_POST['charName'];
$server = $_POST['servers'];
##$_POST['server'];
$bnetAPI = "https://us.api.battle.net/wow/character/";
$apiKey = "apiKeyWouldGoHere";
// Example https://us.api.battle.net/wow/character/$Server/$CharName?locale=en_US&apikey=$apiKey//
$request = $bnetAPI . urlencode($server) .'/'.$charName .'?locale=en_US&apikey=' . $apiKey ;
$response = file_get_contents($request);
$jsonobj = json_decode($response);
}
?>


The 'json_decode' and 'file_get_contents' I got from another thread, because I was getting non object responses. With those $jsonobj is putting out the object I linked above.

test.js

$(document).ready(function () {
$('#myForm').on('submit', function(e) {
e.preventDefault();
$.post('testAPI.php', $(this).serialize(), function (data) {
alert(data);
console.log(data)
return false;
})
});
});


Up until the "function (data)" this script is actually taken from another form I have that works successfully. Currently nothing is happening when I hit submit - No redirect, no response, no console.log - I feel like it's because I'm POSTing, and it needs to GET but then I'd still get 'something' from data?

Would appreciate any input. Also still unable to troubleshoot PHP, unless I run the PHP script directly. I feel this much just be functionality within the language.

Thanks!

UPDATE Placeholder.php

<?php
if (!empty($_POST)) {
$charName = $_POST['charName'];
##$_POST['charName'];
$server = $_POST['servers'];
##$_POST['server'];
$bnetAPI = "https://us.api.battle.net/wow/character/";
$apiKey = "key";
// Example https://us.api.battle.net/wow/character/Thrall/Teodoro?locale=en_US&apikey=$apiKey//
$request = $bnetAPI . $server .'/'.$charName .'?locale=en_US&apikey=' . $apiKey ;
$response = file_get_contents($request);
$jsonobj = json_decode($response);
header('Content-Type: application/json');
echo $response;
exit();
}
?>


UPDATE index.html (just JS portion)

$(document).ready(function () {
$('#myForm').submit(function (e) {
e.preventDefault();

$.post('test2.php', $(this).serialize(), function (data) {
console.log(typeof(data));
if (typeof data === 'string')
data = JSON.parse(data);
if (typeof data !== 'object') {
console.log("failed to parse data");
return;
}
data = JSON.parse(data);
console.log(data);
});
/*

*/
console.log('Data is not returning.');
return false;
});
});

Answer

Your jQuery code refers to a form with myForm ID, but you haven't assigned the ID to the form. So you should add the id attribute as follows

<form id="myForm">

Next, you have to fix the URL you post to. It should be testAPI.php, but not text.php:

$('#myForm').submit(function (e) {
  e.preventDefault();
  $.post('testAPI.php', function (data) {
    // ...
  });
})

Since you are binding the onsubmit, and handling the post request yourself, you probably don't need the action and method attributes in your form. Since the testAPI.php returns JSON content, you need to decode it in the request handler. Also, with the $.post() call you don't send any data to the server. It is just an empty POST request. You have to pass the serialized form as the second argument:

test.js

$('#myForm').submit(function (e) {
  // note, `this` variable refers to the form node.
  e.preventDefault();
  $.post('testAPI.php', $(this).serialize(), function (data) {
    if (typeof data === 'string')
      data  = JSON.parse(data);
    console.log(data);
  });
  return false;
})

The code parses data, if it is a string. The jQuery handler may pass data as Object in case if the response returned Content-Type: application/json (in fact, is the right MIME type for JSON data). So you I'd recommend fixing the MIME type in testAPI.php, and, yes, you should print the response instead of decoding (unless you need to modify it):

header('Content-Type: application/json');
echo $response; // supposed to be a JSON string
exit();

If, however, you need a modified response, then decode it, modify, and encode, again:

header('Content-Type: application/json');
$response = json_decode($response, true);
$response['something'] = 'somevalue';
// unset($response['redundant_field']);
header('Content-Type: application/json');
echo json_encode($response); // supposed to be a JSON string
exit();

Example

test.php

<?php
if (!empty($_POST)) {
  $search_term = $_POST['search-term'];
  $category = $_POST['category'];

  $fake_response = [
    'term' => $search_term,
    'cat' => $category,
    'somethingelse' => date('r'),
  ];

  header('Content-Type: application/json');
  echo json_encode($fake_response);
  exit();
}
?>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <title>Test</title>
  <script
          src="https://code.jquery.com/jquery-3.1.1.min.js"
          integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
          crossorigin="anonymous"></script>
</head>
<body>
  <form id="myForm">
    <input type="search" name="search-term" id="charSearch"/>
    <select name="category" id="servers">
      <option value="optA" selected>optA<option>
      <option value="optB">optB</option>
    </select>
  <input type="submit" name="SubmitButton"/>
  </form>
  <script>
$(document).ready(function () {
  $('#myForm').submit(function (e) {
    e.preventDefault();

    $.post('test.php', $(this).serialize(), function (data) {
      if (typeof data === 'string')
        data = JSON.parse(data);
      if (typeof data !== 'object') {
        console.log("failed to parse data");
        return;
      }
      console.log(data);
    });
    return false;
  });
});
  </script>
</body>
</html>

Sample output (in the browser's console)

Object { term: "rr", cat: "optA", somethingelse: "Sun, 23 Oct 2016 05:10:50 +0000" }
Comments