Introduction
Referring to Heroes' example here, this example is totally created by Angular 2 and typescript. Some people may ask, if it is possible to do the same, using pure JavaScript instead. I decided to make a one, using JavaScript, pure JavaScript, and of course AJAX to call the Server-side functionality. At the Server-side, I coded PHP Web Service that accepts different kinds of requests (GET-POST-PUT-DELETE).
Let’s code first the Server-side
We add this piece of code to accept CORS and establish the database connection.
- <?php
- //ALLOW CROSS-ORIGIN RESOURCE SHARING CORS
- header('Access-Control-Allow-Origin: *');
- header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
- header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE,PUT');
- //-----------------------------
- //ESTABLISH DB CONNECTION
- $db_host = "hostname";
- $db_username = "username";
- $db_password="password";
- $db_name="DBName";
- $db_connection=new MySQLi($db_host,$db_username,$db_password,$db_name);
- if (!$db_connection)
- {
- die("Connection Error" . mysqli_connect_err());
- }
- ?>
In the very first, check the kind of request and then handle each request, using if statements
- $verb=$_SERVER['REQUEST_METHOD'];
To get the associated row names from the result set, get the result and return get_result() into $result variable that has fetch_assoc() method.
- $result= $STMNT_SELECT->get_result();
The full code is given below.
- <?php
- //heroesOnline.php file
- //CONNECTO TO DB
- include_once('config.php');
- //PREPARED STATEMENTS
- //SELECT QUERY
- $querySelect="select id,name from heroes";
- $STMNT_SELECT=$db_connection->prepare($querySelect);
- $STMNT_SELECTBYID=$db_connection->prepare("SELECT id,name from heroes WHERE id=?");
- //INSERT QUERY
- $STMNT_INSERT = $db_connection->prepare("INSERT INTO heroes (Name) VALUES (?)");
- //UPDATE QUERY
- $STMNT_UPDATE=$db_connection->prepare("UPDATE heroes SET Name=? WHERE id=?");
- //DELETE QUERY
- $STMNT_DELETE=$db_connection->prepare("DELETE FROM heroes WHERE id=?");
- //CHECK VERB 'REQUEST TYPE'
- $verb=$_SERVER['REQUEST_METHOD'];
- //ARRAY TO RETURN THE RESULT SET INTO
- $result_set=array();
- //CHECK verb type
- if ($verb=='GET'){
- //Check if ID has been passed to the page
- if (isset($_GET['id']))
- {
- //Check if it is queryable
- $STMNT_SELECTBYID->bind_param("i",$_GET['id']);
- if ($STMNT_SELECTBYID->execute()){
- $STMNT_SELECTBYID->bind_result($id,$name);
- //CONVERT RESULT COMING FORM PREPARED STATEMENT INTO 'mysqli_result'
- //TO BE ABLE TO USE THE METHOD 'fetch_assoc'
- $result= $STMNT_SELECTBYID->get_result();
- $row=$result->fetch_assoc();
- echo json_encode($row);
- } else {
- echo 'ERROR RETURNING DATA WITH THIS ID';
- }
- } else{
- //if $STMNT has data
- if ($STMNT_SELECT){
- $STMNT_SELECT->execute();
- $STMNT_SELECT->bind_result($id,$name);
- //CONVERT RESULT COMING FORM PREPARED STATEMENT INTO 'mysqli_result'
- //TO BE ABLE TO USE THE METHOD 'fetch_assoc'
- $result= $STMNT_SELECT->get_result();
- while ($row=$result->fetch_assoc()){
- //printf ("%d %s <br>", $row["id"], $row["name"]);
- //ADD EACH ROW TO THE ARRAY
- $result_set[]=$row;
- }
- //RETURN JOSN OBJECT OF THE WHOLE ARRAY
- echo json_encode($result_set);
- } //IF
- }
- $STMNT_SELECTBYID->close();
- $STMNT_SELECT->close();
- } elseif ($verb=='POST'){
- echo 'POST method was called';
- $STMNT_INSERT->bind_param("s",$_POST['name']);
- if ($STMNT_INSERT->execute()){
- echo 'INSERTED';
- } else { echo 'INSERT_ERROR'; }
- $STMNT_INSERT->close();
- } elseif ($verb=='DELETE'){
- echo 'DELETE method was called';
- parse_str(file_get_contents('php://input'),$_DELETE);
- $STMNT_DELETE->bind_param("i",$_DELETE['id']);
- if ($STMNT_DELETE->execute() ){
- echo 'DELETED' . $_DELETE['id'];
- } else { echo 'DELETE_ERROR'; }
- $STMNT_DELETE->close();
- } elseif ($verb=='PUT'){
- echo 'PUT method was called';
- parse_str(file_get_contents('php://input'),$_PUT);
- $STMNT_UPDATE->bind_param("si",$_PUT['name'],$_PUT['id']);
- if ($STMNT_UPDATE->execute()){
- echo 'UPDATED';
- } else { echo 'UPDATE_ERROR'; }
- $STMNT_UPDATE->close();
- }
- //close connection
- $db_connection->close();
- ?>
Now, let’s move to the client-side.
Once the page opens, it sends a GET request to the Server to get all the heroes.
- //Call this on page load
- window.onload=function()
- {
- selectAllHeroes();
- }
- //Get all heroes form the server
- var selectAllHeroes=function(){
- xmlhttp4GET.open("GET","http://localhost:8000/HeroesWebservice/heroesOnline.php",true);
- xmlhttp4GET.send();
- }
- //Array to hold all heroes and filtered ones
- var heroes=[];
- var matchedHeroes=[];
- var hero;
Text is coming from the Server is parsed as JSON, as the Server-side function returns json_encode() of the resulting result set.
- //Initiate XMLHttpRequest object for GET method
- xmlhttp4GET=new XMLHttpRequest();
- //return data from the server
- xmlhttp4GET.onreadystatechange=function()
- {
- if (this.readyState==4 && this.status==200) {
- heroes=JSON.parse( this.responseText );
- //Draw panels and fill them with heroes data
- drawPanels(heroes);
- }
- }
Now, comes an important part, it combines the resulting data coming from the Server into the interactive user interface elements, using Bootstrap panels, that invokes the function drawPanls() passing heroes as an argument.
- //Draw panels according to the hero list
- var drawPanels=function(listHeroes){
- //collapse panel for the rows
- tableHeroes='<div class="panel-group" id="accordion">';
- //List items in the 'heroes' Array
- listHeroes.forEach(function(item) {
- tableHeroes+='<div class="panel panel-default"><div class="panel-heading">' +
- '<h4 class="panel-title"><a data-toggle="collapse" data-parent="#accordion" href="#panel' + item.id + '"' +
- ' onclick=' + '"' + 'selectOne(' + item.id + ',' + "'" + item.name + "'" + ')">' + item.name + '</a>' +
- '</h4></div><div id="panel' + item.id + '" class="panel-collapse collapse">' +
- '<div class="panel-body">' + '<h4>ID: ' + item.id + '</h4>' +
- '<h4>Name: ' + item.name + '</h4><br />' + '<input type="button" value="Delete" class="btn btn-danger"' +
- 'onclick="remove(' + item.id + ')"' + '/>'
- + '</div></div></div>';
- });
- tableHeroes+='</div>';
- document.getElementById('div_heroeList').innerHTML=tableHeroes;
- }
Note
There are two XML HTTP objects for GET requests, as we have two different kinds of data received from the Server, using GET request, all heroes data, and the second is one record for a hero related to the given ID.
And here is the full code.
- //Call this on page load
- window.onload=function()
- {
- selectAllHeroes();
- }
- //Get all heroes form the server
- var selectAllHeroes=function(){
- xmlhttp4GET.open("GET","http://localhost:8000/HeroesWebservice/heroesOnline.php",true);
- xmlhttp4GET.send();
- }
- //Array to hold all heroes and filtered ones
- var heroes=[];
- var matchedHeroes=[];
- var hero;
- //variable holding table contents
- var tableHeroes;
- //Initiate XMLHttpRequest object for POST, PUT and DELETE methods
- xmlhttp=new XMLHttpRequest();
- // Return data from the server
- xmlhttp.onreadystatechange=function()
- {
- if (this.readyState==4 && this.status==200) {
- console.log(this.responseText);
- }
- //
- }
- //Initiate XMLHttpRequest object for GET method
- xmlhttp4GET=new XMLHttpRequest();
- //return data from the server
- xmlhttp4GET.onreadystatechange=function()
- {
- if (this.readyState==4 && this.status==200) {
- heroes=JSON.parse( this.responseText );
- //Draw panels and fill them with heroes data
- drawPanels(heroes);
- }
- }
- //Initialize object to get data of one hero from the server
- xmlhttpGetById=new XMLHttpRequest();
- //return hero data
- xmlhttpGetById.onreadystatechange=function(){
- if (this.readyState==4 && this.status==200){
- hero=JSON.parse(this.responseText);
- document.getElementById('lbl_name').innerHTML=hero.name;
- }
- }
- //Draw panels according to the hero list
- var drawPanels=function(listHeroes){
- //collapse panel for the rows
- tableHeroes='<div class="panel-group" id="accordion">';
- //List items in the 'heroes' Array
- listHeroes.forEach(function(item) {
- tableHeroes+='<div class="panel panel-default"><div class="panel-heading">' +
- '<h4 class="panel-title"><a data-toggle="collapse" data-parent="#accordion" href="#panel' + item.id + '"' +
- ' onclick=' + '"' + 'selectOne(' + item.id + ',' + "'" + item.name + "'" + ')">' + item.name + '</a>' +
- '</h4></div><div id="panel' + item.id + '" class="panel-collapse collapse">' +
- '<div class="panel-body">' + '<h4>ID: ' + item.id + '</h4>' +
- '<h4>Name: ' + item.name + '</h4><br />' + '<input type="button" value="Delete" class="btn btn-danger"' +
- 'onclick="remove(' + item.id + ')"' + '/>'
- + '</div></div></div>';
- });
- tableHeroes+='</div>';
- document.getElementById('div_heroeList').innerHTML=tableHeroes;
- }
- //add() function when clicking button 'Add'
- var add=function(){
- //Get txtAdd value
- input=document.getElementById("txtAdd").value;
- //if txtAdd is not empty
- if (input==""){
- document.getElementById('spanAddError').style.display="inline";
- return;
- }
- //send POST requert to the server
- xmlhttp.open("POST","http://localhost:8000/HeroesWebservice/heroesOnline.php",true);
- xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
- xmlhttp.send("name=" + input);
- document.getElementById("txtAdd").value="";
- selectAllHeroes();
- } //end function
- //Fire this on change txtAdd onkeyup
- var txtAdd_onChange=function(txt){
- if (txt.value==""){
- document.getElementById('spanAddError').style.display="inline";
- document.getElementById('btnAdd').disabled=true;
- }
- else{
- document.getElementById('spanAddError').style.display="none";
- document.getElementById('btnAdd').disabled=false;
- }
- } // end function
- //Fire this method on updating the entry
- var update=function() {
- input=document.getElementById("txtEdit").value;
- id=document.getElementById('hiddenID').value;
- //Send data to the server as a PUT request
- xmlhttp.open("PUT","http://localhost:8000/HeroesWebservice/heroesOnline.php",true);
- xmlhttp.send("id=" + id + "&name=" + input);
- //Select all heroes from the server after update.
- selectAllHeroes();
- }
- //Fire this on clicking a panel
- var selectOne=function(id,name){
- document.getElementById('hiddenID').value=id;
- document.getElementById('txtEdit').value=name;
- document.getElementById('lbl_id').innerHTML=id;
- xmlhttpGetById.open("GET","http://localhost:8000/HeroesWebservice/heroesOnline.php?id=" + id,true);
- xmlhttpGetById.send();
- }
- var remove=function(id){
- //Send data to the server as a POST request
- xmlhttp.open("DELETE","http://localhost:8000/HeroesWebservice/heroesOnline.php",true);
- xmlhttp.send("id=" + id);
- selectAllHeroes();
- }
- //Fire this onkeyup for txtSearch
- var search=function(filter){
- //Apply filter when txtSearch is not empty
- if (filter!=""){
- matchedHeroes=heroes.filter( n=>n.name.toLowerCase().search( filter )!=-1 );
- drawPanels(matchedHeroes);
- } else{
- drawPanels(heroes);
- }
- }
I hope, this is useful and let me know if you still have any questions or need any clarifications
Enjoy coding.
Download the full code here.

Join the conversation! Your thoughts help the community grow.