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
-
-
- 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');
-
-
-
-
-
- $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());
- }
-
- ?>
Instead of using the virtual Server used in Angular 2, I wrote some PHP code to handle the different kinds of requests to avoid SQL injection, a prepared statement may come in handy, and more secure to handle the requests coming to the Server...
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
-
-
-
- include_once('config.php');
-
-
-
-
- $querySelect="select id,name from heroes";
- $STMNT_SELECT=$db_connection->prepare($querySelect);
- $STMNT_SELECTBYID=$db_connection->prepare("SELECT id,name from heroes WHERE id=?");
-
-
- $STMNT_INSERT = $db_connection->prepare("INSERT INTO heroes (Name) VALUES (?)");
-
-
- $STMNT_UPDATE=$db_connection->prepare("UPDATE heroes SET Name=? WHERE id=?");
-
-
- $STMNT_DELETE=$db_connection->prepare("DELETE FROM heroes WHERE id=?");
-
-
- $verb=$_SERVER['REQUEST_METHOD'];
-
-
- $result_set=array();
-
-
- if ($verb=='GET'){
-
-
- if (isset($_GET['id']))
- {
-
-
- $STMNT_SELECTBYID->bind_param("i",$_GET['id']);
-
- if ($STMNT_SELECTBYID->execute()){
-
- $STMNT_SELECTBYID->bind_result($id,$name);
-
-
-
-
- $result= $STMNT_SELECTBYID->get_result();
-
- $row=$result->fetch_assoc();
-
- echo json_encode($row);
- } else {
-
- echo 'ERROR RETURNING DATA WITH THIS ID';
- }
-
- } else{
-
-
- if ($STMNT_SELECT){
-
- $STMNT_SELECT->execute();
- $STMNT_SELECT->bind_result($id,$name);
-
-
-
-
- $result= $STMNT_SELECT->get_result();
-
- while ($row=$result->fetch_assoc()){
-
-
-
- $result_set[]=$row;
- }
-
-
- echo json_encode($result_set);
- }
-
- }
-
- $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();
- }
-
-
- $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.
-
- window.onload=function()
- {
- selectAllHeroes();
- }
-
-
- var selectAllHeroes=function(){
-
- xmlhttp4GET.open("GET","http://localhost:8000/HeroesWebservice/heroesOnline.php",true);
- xmlhttp4GET.send();
- }
-
-
- 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.
-
- xmlhttp4GET=new XMLHttpRequest();
-
-
- xmlhttp4GET.onreadystatechange=function()
- {
- if (this.readyState==4 && this.status==200) {
-
- heroes=JSON.parse( this.responseText );
-
-
- 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.
-
- var drawPanels=function(listHeroes){
-
-
- tableHeroes='<div class="panel-group" id="accordion">';
-
-
- 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.
-
- window.onload=function()
- {
- selectAllHeroes();
- }
-
-
- var selectAllHeroes=function(){
-
- xmlhttp4GET.open("GET","http://localhost:8000/HeroesWebservice/heroesOnline.php",true);
- xmlhttp4GET.send();
- }
-
-
- var heroes=[];
- var matchedHeroes=[];
- var hero;
-
-
- var tableHeroes;
-
-
- xmlhttp=new XMLHttpRequest();
-
-
- xmlhttp.onreadystatechange=function()
- {
- if (this.readyState==4 && this.status==200) {
-
-
- console.log(this.responseText);
- }
-
- }
-
-
- xmlhttp4GET=new XMLHttpRequest();
-
-
- xmlhttp4GET.onreadystatechange=function()
- {
- if (this.readyState==4 && this.status==200) {
-
- heroes=JSON.parse( this.responseText );
-
-
- drawPanels(heroes);
- }
- }
-
-
- xmlhttpGetById=new XMLHttpRequest();
-
-
- xmlhttpGetById.onreadystatechange=function(){
-
- if (this.readyState==4 && this.status==200){
-
- hero=JSON.parse(this.responseText);
- document.getElementById('lbl_name').innerHTML=hero.name;
- }
- }
-
-
- var drawPanels=function(listHeroes){
-
-
- tableHeroes='<div class="panel-group" id="accordion">';
-
-
- 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;
- }
-
-
- var add=function(){
-
-
- input=document.getElementById("txtAdd").value;
-
-
- if (input==""){
-
- document.getElementById('spanAddError').style.display="inline";
- return;
- }
-
-
- 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();
-
- }
-
-
- 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;
- }
-
- }
-
-
- var update=function() {
-
- input=document.getElementById("txtEdit").value;
- id=document.getElementById('hiddenID').value;
-
-
- xmlhttp.open("PUT","http://localhost:8000/HeroesWebservice/heroesOnline.php",true);
-
- xmlhttp.send("id=" + id + "&name=" + input);
-
-
- selectAllHeroes();
- }
-
-
- 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){
-
-
- xmlhttp.open("DELETE","http://localhost:8000/HeroesWebservice/heroesOnline.php",true);
-
- xmlhttp.send("id=" + id);
-
- selectAllHeroes();
- }
-
-
-
- var search=function(filter){
-
-
- if (filter!=""){
-
- matchedHeroes=heroes.filter( n=>n.name.toLowerCase().search( filter )!=-1 );
- drawPanels(matchedHeroes);
- } else{
-
- drawPanels(heroes);
- }
-
- }
Note, the relative path to the Web service can be used too, but take care of the folder structure and hierarchy to get both the parts connected together.
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.