Android Question Send list of data to webserver

RUNO

Active Member
Licensed User
Longtime User
The customer's request contains a set of products, their price and some specifications, how do I upload them in one list and save them in the database using a php file?
I read many posts but didn't found what I want, can any one help me
 

TILogistic

Expert
Licensed User
Longtime User
see tutorials:

 
Upvote 0

RUNO

Active Member
Licensed User
Longtime User
see tutorials:


Thanks @oparra

All these tutorials I know, but I don't know what data the user wants to send before.
How do I create a list of the products the user enters
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
If you are sending the data using JSON format then the JsonGenerator can be used to convert the List or Map into JSON string. Use okHttpUtils2 PostString to send the JSON string.
 
Upvote 0

Peter Simpson

Expert
Licensed User
Longtime User
I would create a Map or a List and then I would send it as a JSON to the database (I don't use PHP, that answer is for @aeric to give you ;)).

You don't really need JSON Generator to do that.

Here you go, try these.
B4X:
Sub JSON1
    Dim MapJSON As Map = CreateMap("Aaa" : 1, "Bbb" : 2, "Ccc" : 3, "Ddd" : 4, "Eee" : 5, "Fff" : 6, "Gff" : 7)
    Log(MapJSON.As(JSON).ToString)
End Sub

Sub JSON2
    Dim LstJSON As List = Array As String("Aaa","Bbb", "Ccc", "Ddd", "Eee", "Fff", "Ggg")
    Log(LstJSON.As(JSON).ToString)
End Sub

The code above will give you these...

Map as JSON1
B4X:
{
    "Aaa": 1,
    "Ccc": 3,
    "Bbb": 2,
    "Eee": 5,
    "Ddd": 4,
    "Gff": 7,
    "Fff": 6
}
List as JSON2
B4X:
[
    "Aaa",
    "Bbb",
    "Ccc",
    "Ddd",
    "Eee",
    "Fff",
    "Ggg"
]


Enjoy...
 
Last edited:
Upvote 0

ilan

Expert
Licensed User
Longtime User
The customer's request contains a set of products, their price and some specifications, how do I upload them in one list and save them in the database using a php file?
I read many posts but didn't found what I want, can any one help me

i would create a Type object like:

B4X:
Type product(id As Int, desc As String, price As Float, specs As Map)

then add all products to a list and after that convert, the list objects to a byte object and upload that byte object to SQL DB as type BLOB.

B4X:
Sub object_to_byte(obj As Object)As Byte()
    Dim ser As B4XSerializator
    Return ser.ConvertObjectToBytes(obj)
End Sub

now you can load it back from the db and convert it back to a type object.

B4X:
Sub byte_to_object(data() As Byte)As Object
    Dim ser As B4XSerializator
    Return ser.ConvertBytesToObject(data)
End Sub

note that you convert the whole LIST that contains all types objects in it!
 
Upvote 0

microbox

Active Member
Licensed User
Longtime User
If you are sending the data using JSON format then the JsonGenerator can be used to convert the List or Map into JSON string. Use okHttpUtils2 PostString to send the JSON string.
Hi can you please share a snippet code for this? Like to see the php part.
 
Upvote 0

Peter Simpson

Expert
Licensed User
Longtime User
For price and specs you can just place a map within a map for JSON, nothing too difficult, then just send it as a JSON.

Here, read my tutorial on the subject...
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
on second thought if you want to read the data from different platforms than b4x then JSON is the better choice!
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
Hi can you please share a snippet code for this? Like to see the php part.
I modified a PHP script for one of my apps. Not tested but should give you a rough idea how the PHP part works.
PHP:
<?php
try
    {
        // Check Authentication

        require "database.php";
        $json = file_get_contents("php://input");
        $List1 = array();  
        $List1 = json_decode($json, true);
      
        if (empty($List1))
        {
            // Return JSON to client
            header('HTTP/1.1 400 Bad Request');
            header('Content-Type: application/json');
            $data = array("result" => -1, "message" => "failed", "error" => "Error Empty List");
            print json_encode ($data);
            exit;
        }

        $pdo = Database::connect();
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        // Check user name and password

        $x = 0; // Start reading from 1st row
        while($x < count($List1))
        {
            $Map1 = array();
            $Map1 = $List1[$x];
            $sku = $Map1["sku"];
            $desc = $Map1["desc"];
            $price = $Map1["price"];

            // Insert or Update products
            $query = "REPLACE INTO `tbl_products` (`product_code`, `product_price`, `descriptions`)";
            $query .= " VALUES (:sku, :price, :desc)";
            $db = $pdo->prepare($query);
            $db->bindvalue(":sku", $sku, PDO::PARAM_STR);
            $db->bindvalue(":price", $price, PDO::PARAM_STR);
            $db->bindvalue(":desc", $desc, PDO::PARAM_STR);          
            $db->execute();

            $x++;
        }

        Database::disconnect();
        // Return JSON to client
        header('HTTP/1.1 200 OK');
        header('Content-Type: application/json');
        $data = array("result" => 0, "message" => "success", "error" => null);
        print json_encode ($data);  
    }
    catch (PDOException $e)
    {
        // Log errors to database
        //$this->LogErrorToDB($e->getMessage());
        Database::disconnect();
        // Return JSON to client
        header('HTTP/1.1 500 Internal Server Error');
        header('Content-Type: application/json');
        $data = array("result" => -1, "message" => "failed", "error" => "Error Execute Query");
        print json_encode ($data);      
    }
?>

edit: Check for empty list.
edit2: I tested the script works.
Here is the SQL script to create test table.
SQL:
CREATE TABLE `tbl_products` (
  `product_code` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
  `product_price` double NOT NULL,
  `descriptions` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`product_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
 
Last edited:
Upvote 0

RUNO

Active Member
Licensed User
Longtime User
I modified a PHP script for one of my apps. Not tested but should give you a rough idea how the PHP part works.
PHP:
<?php
try
    {
        // Check Authentication

        require "database.php";
        $json = file_get_contents("php://input");
        $List1 = array();
        $List1 = json_decode($json, true);
    
        if (empty($List1))
        {
            // Return JSON to client
            header('HTTP/1.1 400 Bad Request');
            header('Content-Type: application/json');
            $data = array("result" => -1, "message" => "failed", "error" => "Error Empty List");
            print json_encode ($data);
            exit;
        }

        $pdo = Database::connect();
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        // Check user name and password

        $x = 0; // Start reading from 1st row
        while($x < count($List1))
        {
            $Map1 = array();
            $Map1 = $List1[$x];
            $sku = $Map1["sku"];
            $desc = $Map1["desc"];
            $price = $Map1["price"];

            // Insert or Update products
            $query = "REPLACE INTO `tbl_products` (`product_code`, `product_price`, `descriptions`)";
            $query .= " VALUES (:sku, :price, :desc)";
            $db = $pdo->prepare($query);
            $db->bindvalue(":sku", $sku, PDO::PARAM_STR);
            $db->bindvalue(":price", $price, PDO::PARAM_STR);
            $db->bindvalue(":desc", $desc, PDO::PARAM_STR);        
            $db->execute();

            $x++;
        }

        Database::disconnect();
        // Return JSON to client
        header('HTTP/1.1 200 OK');
        header('Content-Type: application/json');
        $data = array("result" => 0, "message" => "success", "error" => null);
        print json_encode ($data);
    }
    catch (PDOException $e)
    {
        // Log errors to database
        //$this->LogErrorToDB($e->getMessage());
        Database::disconnect();
        // Return JSON to client
        header('HTTP/1.1 500 Internal Server Error');
        header('Content-Type: application/json');
        $data = array("result" => -1, "message" => "failed", "error" => "Error Execute Query");
        print json_encode ($data);    
    }
?>

edit: Check for empty list.
edit2: I tested the script works.
Here is the SQL script to create test table.
SQL:
CREATE TABLE `tbl_products` (
  `product_code` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
  `product_price` double NOT NULL,
  `descriptions` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`product_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Thanks all
@aeric I know all that but the part of b4x what I need.
How I create list/map for products data (input from user)in b4x
 
Last edited:
Upvote 0

aeric

Expert
Licensed User
Longtime User
Thanks all
@aeric I know all that but the part of b4x what I need.
How I create list/map for products data in b4x
As pointed out by @Peter Simpson above, you can easily create JSON string.
B4X:
' Create item map
Dim Item1 As Map = CreateMap("sku" : "003", "price" : 2.25, "desc" : "orange")
Dim Item2 As Map = CreateMap("sku" : "004", "price" : 1.75, "desc" : "apple")
Dim Item3 As Map = CreateMap("sku" : "002", "price" : 5.2, "desc" : "banana")
Dim Item4 As Map = CreateMap("sku" : "001", "price" : 30, "desc" : "durian")

Dim Products As List

' Add items to List

' Method 1
Products.Initialize
Products.Add(Item1)
Products.Add(Item2)
Products.Add(Item3)
Products.Add(Item4)

' Method 2
' Products.Initialize2(Array As Object(Item1, Item2, Item3, Item4))

Dim data As String = Products.As(JSON).ToString

You can also read items from the database and loop through the records then add to the list.
B4X:
Sub Upload
    Dim Query As String = $"SELECT * FROM Products WHERE upload = ?"$
    Dim RS As ResultSet = SQL.ExecQuery2(Query, Array As String(1))
    Dim Products As List
    Products.Initialize
    Do While RS.NextRow
        Dim Item As Map = CreateMap("sku" : RS.GetString("Item_Code"), "price" : RS.GetDouble("Item_Cost"), "desc" : RS.GetString("Item_Name"))
        Products.Add(Item)
    Loop
    RS.Close
    
    Dim data As String = Products.As(JSON).ToString

    Dim job As HttpJob
    job.Initialize("", Me)
    job.PostString("https://mydomain.com/myapp/upload-products.php", data)
    'job.GetRequest.SetHeader("Authorization", "Basic " & Utility.Base64(UserName & ":" & Password))
    Wait For (job) JobDone (job As HttpJob)
    If job.Success Then
        Dim Result As String = job.GetString
        Log(Result)
    Else
        Dim strError As String = job.ErrorMessage
        Log(strError)
    End If
    job.Release
End Sub
 
Upvote 0

RUNO

Active Member
Licensed User
Longtime User
As pointed out by @Peter Simpson above, you can easily create JSON string.
B4X:
' Create item map
Dim Item1 As Map = CreateMap("sku" : "003", "price" : 2.25, "desc" : "orange")
Dim Item2 As Map = CreateMap("sku" : "004", "price" : 1.75, "desc" : "apple")
Dim Item3 As Map = CreateMap("sku" : "002", "price" : 5.2, "desc" : "banana")
Dim Item4 As Map = CreateMap("sku" : "001", "price" : 30, "desc" : "durian")

Dim Products As List

' Add items to List

' Method 1
Products.Initialize
Products.Add(Item1)
Products.Add(Item2)
Products.Add(Item3)
Products.Add(Item4)

' Method 2
' Products.Initialize2(Array As Object(Item1, Item2, Item3, Item4))

Dim data As String = Products.As(JSON).ToString

You can also read items from the database and loop through the records then add to the list.
B4X:
Sub Upload
    Dim Query As String = $"SELECT * FROM Products WHERE upload = ?"$
    Dim RS As ResultSet = SQL.ExecQuery2(Query, Array As String(1))
    Dim Products As List
    Products.Initialize
    Do While RS.NextRow
        Dim Item As Map = CreateMap("sku" : RS.GetString("Item_Code"), "price" : RS.GetDouble("Item_Cost"), "desc" : RS.GetString("Item_Name"))
        Products.Add(Item)
    Loop
    RS.Close
   
    Dim data As String = Products.As(JSON).ToString

    Dim job As HttpJob
    job.Initialize("", Me)
    job.PostString("https://mydomain.com/myapp/upload-products.php", data)
    'job.GetRequest.SetHeader("Authorization", "Basic " & Utility.Base64(UserName & ":" & Password))
    Wait For (job) JobDone (job As HttpJob)
    If job.Success Then
        Dim Result As String = job.GetString
        Log(Result)
    Else
        Dim strError As String = job.ErrorMessage
        Log(strError)
    End If
    job.Release
End Sub

Thanks @aeric

What does it mean this error

2
** Activity (main) Resume **
Error occurred on line: 157 (Main)
android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 2
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:514)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:138)
at android.database.AbstractWindowedCursor.getInt(AbstractWindowedCursor.java:70)
at anywheresoftware.b4a.sql.SQL$CursorWrapper.GetInt(SQL.java:359)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:197)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
 
Upvote 0

KMatle

Expert
Licensed User
Longtime User
Small optimization:

Convert each map to a JSON string before adding it to the list (and vice versa on the php side). Depending on the data (spaces, special chars, etc.) you run into problems due to encoding otherwise.
 
Upvote 0

RUNO

Active Member
Licensed User
Longtime User
Small optimization:

Convert each map to a JSON string before adding it to the list (and vice versa on the php side). Depending on the data (spaces, special chars, etc.) you run into problems due to encoding otherwise.

I wrote like that code only change read method from db .
Error in line of dim item as map = create map
Can anyone explain me the error

B4X:
Dim Products As List

    Products.Initialize

    Do While RS.NextRow

        Dim Item As Map = CreateMap("sku" : RS.GetString("Item_Code"), "price" : RS.GetDouble("Item_Cost"), "desc" : RS.GetString("Item_Name"))

        Products.Add(Item)

    Loop

    RS.Close

  

    Dim data As String = Products.As(JSON).ToString
 
Last edited:
Upvote 0

RUNO

Active Member
Licensed User
Longtime User
Log the value of SQLite columns.
Do you have column name "Item_Code" and so on (the other 2 columns) in your SQLite database?
I think your table may not having same column names as mine.




B4X:
sql1.ExecNonQuery("CREATE  TABLE IF NOT EXISTS cart (item INTEGER, name TEXT ,qty INTEGER, price TEXT)")
part of fill list
error in createmap
B4X:
For i=1 To cursor.RowCount
        Dim Item As Map = CreateMap("item" : cursor.GetInt("item"), "name" : cursor.GetString("name"), "price" : cursor.GetString("price"))
      '
  Products.Add(Item)
    Next
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
B4X:
sql1.ExecNonQuery("CREATE  TABLE IF NOT EXISTS cart (item INTEGER, name TEXT ,qty INTEGER, price TEXT)")
part of fill list
error in createmap
B4X:
For i=1 To cursor.RowCount
        Dim Item As Map = CreateMap("item" : cursor.GetInt("item"), "name" : cursor.GetString("name"), "price" : cursor.GetString("price"))
      '
  Products.Add(Item)
    Next
You made first mistake to start i =1 unless you purposely skip first item (index=0) and you are very sure you have at least 2 items.
You make second mistake to loop until cursor.RowCount which you actually should stop looping at cursor.RowCount - 1.
Then the third mistake is you never use the i variable to assign to the cursor.Position = i.
The fourth mistake is you should not use TEXT for price unless you purposely design as it is.

And please avoid using Cursor instead use Resultset as in my code.
B4X:
Dim RS As ResultSet = SQL.ExecQuery("SELECT * FROM cart")
Dim Products As List
Products.Initialize
Do While RS.NextRow
    Dim Item As Map = CreateMap("item" : RS.GetInt("item"), "name" : RS.GetString("name"), "price" : RS.GetDouble("price"), "qty" : RS.GetInt("qty"))
    Products.Add(Item)
Loop
RS.Close
 
Upvote 0

RUNO

Active Member
Licensed User
Longtime User
You made first mistake to start i =1 unless you purposely skip first item (index=0) and you are very sure you have at least 2 items.
You make second mistake to loop until cursor.RowCount which you actually should stop looping at cursor.RowCount - 1.
Then the third mistake is you never use the i variable to assign to the cursor.Position = i.
The fourth mistake is you should not use TEXT for price unless you purposely design as it is.

Thanks @aeric
All of your instructions matter to me.
 
Upvote 0
Top