Home > Software design >  How to writing URL of lazy loading in flutter
How to writing URL of lazy loading in flutter

Time:08-12

I make one listview and I want make it work with lazy loading. I get the data from MySQL by php file. My problem the data is not cut. I found example online and by it I understand what is the problem in my code but I can't understand how to solve it. The problem in my URL keyword of limit. This is my php file:

<?php


include 'con.php';



$sql = "SELECT  name FROM User ORDER BY id DESC";


$stmt = $con->prepare($sql); 


$stmt->execute();
$result = $stmt->get_result();
$json = [];
if ($result) {
    while ($row = $result->fetch_assoc()) {
        $json[] = $row;
    }
}
echo json_encode($json, JSON_NUMERIC_CHECK);

?>

And This how I get data:

  void _firstLoad() async {
setState(() {
  _isFirstLoadRunning = true;
});

try {


  final res =
  await http.get(Uri.parse("$_baseUrl?_page=$_page&_limit=$_limit"));
  setState(() {
    _posts = json.decode(res.body);
  });
} catch (err) {
  if (kDebugMode) {
    print('Something went wrong');
  }
}

setState(() {
  _isFirstLoadRunning = false;
});}

The problem in this keyword from above code:

&_limit=

What should I write here? From where I get this keyword? Do I have to add it to a php file?

Full code:

class _HomePageState extends State<HomePage> {
  //final _baseUrl = 'https://jsonplaceholder.typicode.com/posts';
  final _baseUrl = 'https://***************.php';
  int _page = 0;

  final int _limit = 2;

  bool _isFirstLoadRunning = false;
  bool _hasNextPage = true;

  bool _isLoadMoreRunning = false;

  List _posts = [];

  void _loadMore() async {
  /*  if (_hasNextPage == true &&
        _isFirstLoadRunning == false &&
        _isLoadMoreRunning == false &&
        _controller.position.extentAfter < 300
    ) {
      setState(() {
        _isLoadMoreRunning = true; // Display a progress indicator at the bottom
      });

      _page  = 1; // Increase _page by 1

      try {
        final res =
        await http.get(Uri.parse("$_baseUrl?_page=$_page&_limit=$_limit"));

        final List fetchedPosts = json.decode(res.body);
        if (fetchedPosts.isNotEmpty) {
          setState(() {
            _posts.addAll(fetchedPosts);
          });
        } else {

          setState(() {
            _hasNextPage = false;
          });
        }
      } catch (err) {
        if (kDebugMode) {
          print('Something went wrong!');
        }
      }


      setState(() {
        _isLoadMoreRunning = false;
      });
    }*/
  }

  void _firstLoad() async {
    setState(() {
      _isFirstLoadRunning = true;
    });

    try {


      final res =
      await http.get(Uri.parse("$_baseUrl?_page=$_page&_limit=$_limit"));//==== here problem====

      setState(() {
        _posts = json.decode(res.body);
      });
    } catch (err) {
      if (kDebugMode) {
        print('Something went wrong');
      }
    }

    setState(() {
      _isFirstLoadRunning = false;
    });
  }

  late ScrollController _controller;
  @override
  void initState() {
    super.initState();
    _firstLoad();
    _controller = ScrollController()..addListener(_loadMore);

  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Your news', style: TextStyle(color: Colors.white),),
        ),
        body:_isFirstLoadRunning?const Center(
          child: CircularProgressIndicator(),
        ):Column(
          children: [
            Expanded(
              child: ListView.builder(
                itemCount: _posts.length,
                controller: _controller,
                itemBuilder: (_, index) => Card(
                  margin: const EdgeInsets.symmetric(
                      vertical: 8, horizontal: 10),
                  child: ListTile(
                    title: Text(_posts[index]['name']),
                   // subtitle: Text(_posts[index]['body']),
                  ),
                ),
              ),
            ),
            if (_isLoadMoreRunning == true)
              const Padding(
                padding: EdgeInsets.only(top: 10, bottom: 40),
                child: Center(
                  child: CircularProgressIndicator(),
                ),
              ),

            if (_hasNextPage == false)
              Container(
                padding: const EdgeInsets.only(top: 30, bottom: 40),
                color: Colors.amber,
                child: const Center(
                  child: Text('You have fetched all of the content'),
                ),
              ),
          ],
        )
    );
  }
}


Can someone help me. thank you.

CodePudding user response:

First, in PHP remove the JSON_NUMERIC_CHECK flag. If you have a name in database that will be a number, it will be send as "name"=15 instead of "name"="15"

In you PHP script you don't use parameters _page and _limit you pass to the script. So update you SQL request with LIMIT and OFFSET in order to paginate datas. Here you are sending all data at each PHP script call.

$sql = "SELECT name FROM User ORDER BY id DESC LIMIT " . intval($_GET["_limit"]) . "OFFSET " . intval(_limit) * intval($_GET["_page"]);

When you call an API always check returned responseCode for not parsing data as errors:

try {
    final res = await http.get(Uri.parse(`${_baseUrl}?_page=${_page}&_limit=${_limit}`));//==== here problem====

    if (response.statusCode == 200) {
        setState(() {
          _posts = json.decode(res.body);
        });
    }
} catch (err) {
  if (kDebugMode) {
    print('Something went wrong: '   err.toString());
  }
}
  • Related