Converting Ajax script from jQuery to vanilla JS

I’m trying to convert a little script to vanilla JS.

$(document).ready(function(){
	$('#searchText').keyup(function(){
		var txt = $('#searchText').val();
		$.ajax({
			url:'getClient.php',
			method:"post",
			data:{search_name: txt},
			dataType:"text",
			success: function(data){
				$('#search-result').html(data);
			}
		});
	});
});

I’m part-way there…

const s = document.querySelector("#searchText");
s.addEventListener("keyup", function() {
	const txt = s.value;
	//console.log(txt);
	fetch("getClient.php")
	.then (response => response.text())
	.then (text => s.innerHTML = text)
});

but it tells me text() is not a function.

   /* retrieve search*/
    const retrieveSearchUISuccess = function (info) {
        displaySearch(info);

    };

    /* If Database Table fails to load or what have you */
    const retrieveSearchUIError = function (error) {
        console.log("Database Table did not load", error);
    };

    /* Call Fetch Search */
    const callSearch = (retrieveUrl, succeed, fail) => {

        fetch(retrieveUrl, {
            method: 'POST', // or 'PUT'
            body: JSON.stringify(text)
        })
            .then((response) => handleErrors(response))
            .then((data) => succeed(data))
            .catch((error) => fail(error));
    };

    /* Handle General Errors in Fetch */
    const handleErrors = function (response) {
        if (!response.ok) {
            throw (response.status + ' : ' + response.statusText);
        }
        return response.json();
    };

const s = document.querySelector("#searchText");
s.addEventListener("keyup", function() {
	let text.value = s.value; // I usually make this a global variable as it's a couple layers deep
        callSearch('getClient.php', retrieveSearchUISuccess, retrieveSearchUIError);
});

Something like the above might work?
HTH John

1 Like

Thanks, @Pepster64

I spotted the checkUISuccess and checkUIError :slight_smile: but I’m struggling with the rest.

let text.value = s.value; gives a syntax error. I’ve tried just let text = s.value; and I’ve tried making it 2 lines but that doesn’t help.

Well Pepster’s code assumes your data is JSON. (return response.json(); at the end of handleErrors.)

response.text() being not a function implies that the response object didnt get created.

Your code as written in the OP looks correct, other than you didnt put the txt value anywhere :stuck_out_tongue:

1 Like

Thanks, squire

That’s good to know.

Ah yes. I’m not sure how I pass that as a POST variable to the PHP script.

Okay, so I have discovered how to send it using POST method.

const s = document.querySelector("#searchText");
s.addEventListener("keyup", function() {
  const txt = s.value;
  //console.log(txt);
  fetch("getClient.php", {
    method: "POST"
  })
  .then (response => response.text())
  .then (text => s.innerHTML = text)
});

but I still haven’t discovered how to do the equivalent of jQuery’s

data:{search_name: txt},
dataType:"text",

dataType just tells jQuery’s response handler how to process the result - so in vanilla you don’t do that, you just handle it in whatever way you need to (response.text())

data… there’s a couple ways to go about it, but there’s an example of one way in Pepster’s post:

I believe from context clues at that point text is an element reference to a text field.

MDN’s example:

const data = { username: 'example' };
fetch('https://example.com/profile', {
  method: 'POST', // or 'PUT'
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(data),
})

Two notes:
1: content-type should be intelligent and not necessarily need to be set by you; YMMV.
2: you should also be able to pass something like new URLSearchParams(new FormData(yoursearchfield)) as the body parameter, and get a multipart/form-data content type instead.

1 Like

Thanks. I think I’m getting somewhere one step at a time. So it’s the ‘body’ that gets sent, so now I need to figure how to send it as $_POST['search_name'].

const s = document.querySelector("#searchText"),
  r = document.querySelector("#search-result");
s.addEventListener("keyup", function() {
  const txt = s.value;
  //console.log(txt);
  fetch("getClient.php", {
    method: "POST",
    body: JSON.stringify(txt)
  })
  .then (response => response.text())
  .then (text => r.innerHTML = text)
});

I’m struggling with this. :blush:

Okay another penny has dropped. :slight_smile: Another iteration:

const s = document.querySelector("#searchText"),
  r = document.querySelector("#search-result");
s.addEventListener("keyup", function() {
  const data = { search_name: s.value };
  //console.log(data);
  fetch("getClient.php", {
    method: "POST",
    body: JSON.stringify(data)
  })
  .then (response => response.text())
  .then (text => r.innerHTML = text)
});

It’s not working. The PHP script is receiving an empty POST array. I’m thinking

const data = { search_name: s.value };

isn’t quite right?

Evening Squire.

When using the Fetch API to send data to a PHP server, you’ll have to handle the request a little differently from what you’re used to.

The data you’re POSTing is not going to be available in the super global variables since this input is not coming from a multipart-data form or an application/x-www-form-urlencoded.

See here for more details: https://stackoverflow.com/questions/33439030/how-to-grab-data-using-fetch-api-post-method-in-php

There are a number of ways around this, but the easiest path here is to send the data as FormData. Here is a simple example for you to play around with:

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Fetch demo</title>
  </head>
  <body>

    <input id="searchText" />
    <div id="searchResult"></div>

    <script>
      const s = document.querySelector("#searchText");
      const r = document.querySelector("#searchResult");
      const formData = new FormData();

      s.addEventListener("keyup", function() {
        formData.append('search_term', s.value)

        fetch("getClient.php", {
          method: "POST",
          body: formData
        })
        .then (response => response.text())
        .then (text => r.innerHTML = text)
      });
    </script>
  </body>
</html>

getClient.php

<?php
  echo $_POST['search_term'];
?>

This just echos the search term right back at you, but hopefully it is enough to demonstrate the concept.


Another thing you might want to think about when you’ve got this working is to debounce the keyup event, so that your server is not hammered by requests on every keystroke.

2 Likes

Yey! Thanks, good sir.

It also helps if I get the variable names right. :blush:

2 Likes