Saturday, 5 December 2020

How to Phonegap Data Storage on Server?

 

Introduction

There are many situations where data cannot be stored on the mobile device and to be stored on a server. Especially, if you have to store large volumes of data, then it would not be practical to store it in a mobile device that has only limited memory. Also, data that gets changed constantly, like weather data, stock data, currency conversion details etc, is also fetched from a server. We have already seen how to get data from a server with the help of web services in the SOA chapter. The same technique can be used to retrieve data from a server.

Create a Currency Conversion App

We are going to create a currency conversion app. You can get a currency conversion web service at the address “https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml”. But you cannot use this web service directly using XMLHttpRequest object, that is using AJAX. The issue is that this web service is not allowing us to use it from a different domain. A web service can be accessed from another domain only if it provides cross domain access permission. It is done by setting a specific header “Access-Control-Allow-Origin”. As you cannot see this at the top of the xml document, we cannot access it using AJAX.

So, how will we proceed? I am going to write a PHP program to access this xml file and store the information in an array which is very much allowed. Then, we will fetch the required details from the array. Before writing our own PHP program, just try to understand what you want to achieve through this app. If you have used sites like coinmill.org, you might be knowing what currency conversion is. Suppose, an Indian freelancer has earned 300 US Dollars and he wants to transfer that amount as Indian Rupees into his bank account. So, he will be interested to know how much money (in Indian Rupees) he will get for 300 US Dollars.

We need to have two drop downs, one to select from currency (in this case US Dollar) and second one to select to currency (in this case Indian Rupee) and a textbox to enter the amount he wants to calculate (in this case 300). Then, we also need to have a button on the click of which we will contact the server and get the required data. We are also going to add a <div> to display the result.

Now you have the web service at https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml. But do you know how to calculate the conversion? We need to do a bit of maths here. If you see the xml, you could find rate values for different currencies. If you divide the rate of to currency by the rate of from currency, you will get the converted value for one unit. To make it clear, just consider our previous example where we want to convert USD to INR. Suppose, the rate of INR is 75 and the rate of USD is 1.5. Then 75/1.5, that is 50, is the amount of Indian Rupees for 1 USD. In other words, 1 USD = 50 Indian Rupees (assuming rate of INR is 75 and rate of USD is 1.5). Now, you just need to multiply this with 300 to calculate the total amount. Hope you understand this simple logic.

Let us create the web service now. Open your favourite text editor, copy the following lines of code into a new file and save the file as ConvertCurrency.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
$fromCurr = $_GET["from"];
$toCurr = $_GET["to"];
foreach($currencyXml->Cube->Cube->Cube as $info)
{
    $currArray[] = array(
                "rate" => (float)$info['rate'],
                "currency" => (string)$info['currency']);
}
foreach($currArray as $row)
{
    if($row['currency'] == $fromCurr)
    {
        $fromVal = $row['rate'];
    }
    if($row['currency'] == $toCurr)
    {
        $toVal = $row['rate'];
    }
}
header("Access-Control-Allow-Origin: *");
header("Content-Type: text/xml; charset=utf-8");
$output = "<?xml version='1.0' encoding='ISO-8859-1'?>";
$output .= "<rates>";
$output .= "<fromRate>" . $fromVal . "</fromRate>";
$output .= "<toRate>" . $toVal . "</toRate>";
$output .= "</rates>";
echo $output;
?>

Save this file inside your inetpub/www folder (if you are using IIS) or htdocs/xampp folder(if you are using Apache) so that you can access the web service from your local server. The simplexml_load_file is a very useful PHP function that converts an XML file into a SimpleXMLElement object. Once the file becomes an object, it is so easy to fetch the required data. I am storing the whole information (rate and currency details for all currencies) in an array named currArray. Them I am collecting the rate for the from currency and to currency in fromVal and toVal variables.

In fact, I can easily do the processing here itself and pass the converted value as a string. In that case, we will get the output using responseText. In real life scenarios, many web services return output as XML. So, I have intentionally tried to pass an XML document here, so that you can learn how to collect an XML output using responseXML and then process it to collect the required data. If you pass the value of from as USD and to as INR to this web service, then the output XML will be in the following format (value could be different).

xml.png

Notice that I have added the Access-Control-Allow-Origin header to provide cross domain permission.

Create an App

Let’s create a mobile app for iOS platform this time. Create a project named iOSCurrencyConversion on the desktop. Once the project is created on the desktop, open the folder and double click the iOSCurrencyConversion.xcodeproj icon to launch the project in the XCode environment. Again go back to the project folder on the desktop, open the index.html file inside the www folder using your favourite text editor and clean it up. You can also change the title to “Currency Conversion App”.

Create two drop downs, for from and to currency. We will also add a textbox to enter the amount and a button. On the click of the button, we will contact the server and get the required data. We will also add a <div> to display the conversion details.

Add the following lines of code inside the <body> tag.

From Currency:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<select id="from">
         <option value="AUD">Australian Dollar AUD</option>
         <option value="BGN">Bulgarian Lev BGN</option>
         <option value="INR">Indian Rupee INR</option>
         <option value="JPY">Japanese Yen JPY</option>
         <option value="GBP">Pound Sterling</option>
         <option value="USD" selected>US Dollar USD</option>
        </select><br />
 
        To Currency:
 
        <select id="to">
         <option value="AUD">Australian Dollar AUD</option>
         <option value="BGN">Bulgarian Lev BGN</option>
         <option value="INR" selected>Indian Rupee INR</option>
         <option value="JPY">Japanese Yen JPY</option>
         <option value="GBP">Pound Sterling</option>
         <option value="USD">US Dollar USD</option>
        </select><br />
        Amount to Convert:<input type="text" id="amount" value="1"/><br />
        <input type="button" id="btnConvert" value="Convert" /><br />
        <div id="details"></div>

You can add as many currencies as you want in both the drop downs. Only thing is that those currencies should be available in the web service at https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml.

Add the following lines of code inside the <head> section to check whether the device is ready. Once the device is ready, we will add the event listener for the click event of the button.

1
2
3
4
5
6
7
8
9
10
11
<script>
            var xmlhttp;
            window.onload = function()
            {
                document.addEventListener('deviceready', init, false);
            }
            function init()
            {
                document.getElementById("btnConvert").addEventListener('click', sendData, false);
            }
</script>

Next, we need to write the sendData function.

1
2
3
4
5
6
7
8
9
10
function sendData()
            {
                var from = document.getElementById('from').value;
                var to = document.getElementById('to').value;
                url = ""http:// 192.188.68.12/ConvertCurrency.php?from=" + from + "&to=" + to;
                xmlhttp = new XMLHttpRequest();
                xmlhttp.onreadystatechange = processOutput;
                xmlhttp.open("GET", url, true);
                xmlhttp.send();
            }

Here, you should replace the url address with your machine's IP address. Now, we need to write the processOutput function which will be invoked when the readyState value changes.

1
2
3
4
5
6
7
8
9
10
11
12
function processOutput()
            {
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
                {
                    var info = xmlhttp.responseXML;
                    var fromVal = info.getElementsByTagName('fromRate')[0].firstChild.nodeValue;
                    var toVal = info.getElementsByTagName('toRate')[0].firstChild.nodeValue;
                    var amt = document.getElementById("amount").value;
                    var conversion = Math.round((toVal/fromVal)*amt,3);
                    document.getElementById("details").innerHTML = amt + " " + document.getElementById('from').value + " = " + conversion + " " + document.getElementById('to').value;
                }
            }

As you see, I have used the responseXML property (instead of responseText) to collect the output from the service. Then, I have collected the fromRate (the rate of from currency) and toRate (the rate of to currency). If you try to access the value using getElementsByTagName('fromRate'), you will not get any output. In fact, we are trying to get the first value of fromRate (first value means index is 0). The getElementsByTagName('fromRate')[0] would return a node collection from which we need the node value of its first child.

Finally, we did our math: we calculated (toVal/fromVal) to get the conversion rate for single unit and then multiplied the value by amt to get the actual value. We have also used the round function to round the value to three decimals. Finally, we formatted the output to display in an easily understandable manner. The format is 300 USD = 18000 INR.

Save the index.html file and then run the project from the XCode environment. You will get a screen like this:

first.png

The elements are showing the default values we have set. You can change the values in both the drop downs and the textbox the way you want. Suppose, you changed it like this:

second.png

Once you click the Convert button, you will get the output like this:

third.png

Make sure that you are connected to Internet while running this app because we are accessing the currency conversion rates from the web service online.

No comments:

Post a Comment