Fetching Data From MySql Database To Flutter App
By Webotapp Academy•
<!-- wp:paragraph -->\n<p>This article has two Parts</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true} -->\n<ol><!-- wp:list-item -->\n<li>PHP API for fetching data</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Flutter Screen of Orders</li>\n<!-- /wp:list-item --></ol>\n<!-- /wp:list -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\">Part 1: PHI API Explanation</h3>\n<!-- /wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Explanation of PHP code step by step:</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true} -->\n<ol><!-- wp:list-item -->\n<li><strong>Include Necessary Files:</strong></li>\n<!-- /wp:list-item --></ol>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code> include('cors.php');\n include('../database.php');</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:paragraph -->\n<p>These lines include two external PHP files: <code>cors.php</code> and <code>database.php</code>. These files likely contain functions or configurations needed for handling CORS (Cross-Origin Resource Sharing) and database connection setup.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true,\"start\":2} -->\n<ol start=\"2\"><!-- wp:list-item -->\n<li><strong>Set Response Content Type:</strong></li>\n<!-- /wp:list-item --></ol>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code> header('Content-Type: application/json');</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:paragraph -->\n<p>This line sets the response's content type to JSON. It indicates that the server will send JSON data in the response.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true,\"start\":3} -->\n<ol start=\"3\"><!-- wp:list-item -->\n<li><strong>Initialize an Empty Response Array:</strong></li>\n<!-- /wp:list-item --></ol>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code> $response = array();</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:paragraph -->\n<p>An empty associative array called <code>$response</code> is created to store the response data, including success status, a message, and the order data.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true,\"start\":4} -->\n<ol start=\"4\"><!-- wp:list-item -->\n<li><strong>Check the Request Method:</strong></li>\n<!-- /wp:list-item --></ol>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code> if ($_SERVER['REQUEST_METHOD'] === 'GET') {</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:paragraph -->\n<p>This conditional statement checks if the HTTP request method is a GET request. It ensures that the code below is executed only for GET requests.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true,\"start\":5} -->\n<ol start=\"5\"><!-- wp:list-item -->\n<li><strong>Retrieve Mobile Number from Query Parameters:</strong></li>\n<!-- /wp:list-item --></ol>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code> $mobile = $_GET['mobile'];</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:paragraph -->\n<p>It retrieves the mobile number from the query parameters of the GET request. This mobile number will be used to filter orders.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true,\"start\":6} -->\n<ol start=\"6\"><!-- wp:list-item -->\n<li><strong>Prepare SQL Query to Fetch Orders:</strong></li>\n<!-- /wp:list-item --></ol>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code> $sql = \"SELECT * FROM checkout WHERE c_mobile = :mobile\";\n $stmt = $conn->prepare($sql);\n $stmt->bindParam(':mobile', $mobile);</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:paragraph -->\n<p>These lines prepare an SQL query to fetch orders from a table named <code>checkout</code> where the <code>c_mobile</code> column matches the provided mobile number. It uses a prepared statement to safely bind the <code>:mobile</code> parameter.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true,\"start\":7} -->\n<ol start=\"7\"><!-- wp:list-item -->\n<li><strong>Execute the SQL Query:</strong></li>\n<!-- /wp:list-item --></ol>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code> if ($stmt->execute()) {</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:paragraph -->\n<p>This conditional statement checks if the SQL query executed successfully.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true,\"start\":8} -->\n<ol start=\"8\"><!-- wp:list-item -->\n<li><strong>Fetch Orders and Build the Response:</strong></li>\n<!-- /wp:list-item --></ol>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code> $orders = $stmt->fetchAll(PDO::FETCH_ASSOC);\n $response['success'] = true;\n $response['message'] = \"Orders fetched successfully.\";\n $response['data'] = $orders;</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:paragraph -->\n<p>If the query execution is successful, it fetches the orders as an array of associative arrays. Then, it sets the response's <code>success</code> status to true, provides a success message, and includes the fetched order data in the response.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true,\"start\":9} -->\n<ol start=\"9\"><!-- wp:list-item -->\n<li><strong>Handle Execution Errors:</strong></li>\n<!-- /wp:list-item --></ol>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code> } else {\n $response['success'] = false;\n $response['message'] = \"Error: \" . $stmt->errorInfo();\n }</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:paragraph -->\n<p>In case the SQL query execution encounters an error, it sets the <code>success</code> status to false and includes an error message in the response.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:list {\"ordered\":true,\"start\":10} -->\n<ol start=\"10\"><!-- wp:list-item -->\n<li><strong>Invalid Request Method Handling:</strong> <code>} else { $response['success'] = false; $response['message'] = \"Invalid request method.\"; }</code> If the request method is not a GET request, it sets the <code>success</code> status to false and provides a message indicating that the request method is invalid.</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li><strong>Output the Response as JSON:</strong><br><code>php echo json_encode($response);</code><br>Finally, the code converts the <code>$response</code> array into a JSON string and sends it as the response to the client.</li>\n<!-- /wp:list-item --></ol>\n<!-- /wp:list -->\n\n<!-- wp:paragraph -->\n<p>This code is designed to handle GET requests for fetching orders by mobile number from a database and respond with the retrieved data in JSON format. The response includes information about the success of the operation and, if successful, the fetched order data.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\">Part 2: Flutter Screen Explanation</h3>\n<!-- /wp:heading -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>import 'dart:convert';\nimport 'package:flutter/material.dart';\nimport 'package:http/http.dart' as http;</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:list -->\n<ul><!-- wp:list-item -->\n<li>In this part, we import necessary libraries for the Flutter application. We import <code>dart:convert</code> for JSON decoding, <code>package:flutter/material.dart</code> for Flutter widgets, and <code>package:http/http.dart</code> as <code>http</code> to make HTTP requests.</li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>class Orders extends StatefulWidget {\n const Orders({Key? key}) : super(key: key);\n @override\n State<Orders> createState() => _OrdersState();\n}</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:list -->\n<ul><!-- wp:list-item -->\n<li>Here, we define a Flutter widget called <code>Orders</code>. It extends <code>StatefulWidget</code>, indicating that its state can change. It has a constructor and a method that returns the state object <code>_OrdersState</code>.</li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>class _OrdersState extends State<Orders> {\n final TextEditingController mobileController = TextEditingController();\n List<Map<String, dynamic>> orders = [];\n bool isLoading = false;</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:list -->\n<ul><!-- wp:list-item -->\n<li>This is the state class for the <code>Orders</code> widget. It includes a <code>TextEditingController</code> for handling user input, a list of orders as maps, and a boolean <code>isLoading</code> to track whether data is being loaded.</li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>void searchOrders() async {\n setState(() {\n isLoading = true;\n });</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:list -->\n<ul><!-- wp:list-item -->\n<li><code>searchOrders()</code> is a method that is called when the user clicks the search button. It sets <code>isLoading</code> to true to indicate that data retrieval is in progress.</li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>// Replace with your API endpoint.\nfinal apiUrl = Uri.parse('https://booppers.tk/api/fetch_order.php?mobile=${mobileController.text}');</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:list -->\n<ul><!-- wp:list-item -->\n<li>This line creates a URI for the API endpoint to fetch orders. It includes the user's input (mobile number) as a query parameter.</li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>final response = await http.get(apiUrl);</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:list -->\n<ul><!-- wp:list-item -->\n<li>This line sends an HTTP GET request to the API endpoint using the <code>http</code> package and awaits the response.</li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>if (response.statusCode == 200) {\n final Map<String, dynamic> data = json.decode(response.body);\n if (data['success']) {\n setState(() {\n orders = List<Map<String, dynamic>>.from(data['data']);\n });\n } else {\n // Handle API error here\n }\n} else {\n // Handle API request error here\n}</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:list -->\n<ul><!-- wp:list-item -->\n<li>Here, we check the HTTP status code of the response. If it's 200 (OK), we parse the response body as JSON and check if the 'success' field in the data is true. If so, we update the <code>orders</code> list with the retrieved data. If 'success' is false, you can add error handling for API errors. If the status code is not 200, you can handle request errors.</li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>setState(() {\n isLoading = false;\n});</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:list -->\n<ul><!-- wp:list-item -->\n<li>Finally, after handling the API response or errors, we set <code>isLoading</code> back to false to indicate that data retrieval is complete.</li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->\n\n<!-- wp:paragraph -->\n<p>The remaining code is related to building the user interface, including widgets like <code>Container</code>, <code>TextField</code>, <code>ElevatedButton</code>, and <code>DataTable</code>, along with their properties and styles. This code allows users to search for orders by mobile number and displays the results in a horizontally scrollable <code>DataTable</code>. If no orders are found, it displays a \"No orders found\" message.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p><strong>Fluu Code Of Flutter Screen</strong>:</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>import 'dart:convert';\nimport 'package:flutter/material.dart';\nimport 'package:http/http.dart' as http;\n\nclass Orders extends StatefulWidget {\n const Orders({Key? key}) : super(key: key);\n @override\n State<Orders> createState() => _OrdersState();\n}\n\nclass _OrdersState extends State<Orders> {\n final TextEditingController mobileController = TextEditingController();\n List<Map<String, dynamic>> orders = [];\n bool isLoading = false;\n\n void searchOrders() async {\n setState(() {\n isLoading = true;\n });\n\n // Replace with your API endpoint.\n final apiUrl =\n Uri.parse('https://booppers.tk/api/fetch_order.php?mobile=${mobileController.text}');\n\n final response = await http.get(apiUrl);\n\n if (response.statusCode == 200) {\n final Map<String, dynamic> data = json.decode(response.body);\n if (data['success']) {\n setState(() {\n orders = List<Map<String, dynamic>>.from(data['data']);\n });\n } else {\n // Handle API error here\n }\n } else {\n // Handle API request error here\n }\n\n setState(() {\n isLoading = false;\n });\n }\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n appBar: AppBar(\n title: Text('Search Orders'),\n backgroundColor: Colors.pink,\n ),\n body: SingleChildScrollView(\n child: Column(\n children: [\n Container(\n margin: EdgeInsets.all(30),\n child: Image.network('https://your-image-url-here.com'),\n ),\n Container(\n margin: EdgeInsets.all(10),\n alignment: Alignment.center,\n child: Text('Search Orders', style: TextStyle(fontSize: 25),),\n ),\n Padding(\n padding: const EdgeInsets.all(16.0),\n child: TextField(\n controller: mobileController,\n decoration: InputDecoration(\n labelText: 'Enter Mobile Number',\n border: OutlineInputBorder(\n borderRadius: BorderRadius.circular(10),\n ),\n ),\n ),\n ),\n ElevatedButton(\n onPressed: searchOrders,\n child: Text('Search'),\n ),\n if (isLoading)\n CircularProgressIndicator()\n else if (orders.isNotEmpty)\n SingleChildScrollView(\n scrollDirection: Axis.horizontal, // Enable horizontal scrolling\n child: DataTable(\n columns: const <DataColumn>[\n DataColumn(label: Text('Order ID')),\n DataColumn(label: Text('Customer Name')),\n DataColumn(label: Text('Mobile')),\n DataColumn(label: Text('State')),\n DataColumn(label: Text('Address')),\n ],\n rows: orders.map((order) {\n return DataRow(\n cells: <DataCell>[\n DataCell(Text(order['id'].toString())),\n DataCell(Text(order['c_name'].toString())),\n DataCell(Text(order['c_mobile'].toString())),\n DataCell(Text(order['c_state'].toString())),\n DataCell(Text(order['c_address'].toString())),\n ],\n );\n }).toList(),\n ),\n )\n else\n Text('No orders found.'),\n ],\n ),\n ),\n );\n }\n}\n</code></pre>\n<!-- /wp:code -->