Search code examples
flutterrestdartwoocommercewoocommerce-rest-api

Data not displaying in home page of the flutter app


I tried to fetch products data from Woocommerce API and try to display this data on home page of the flutter but I am not able to display data on the front page. I am getting response.body successful and its printing in terminal but I don't know why its not displaying on home screen. Can someone please help me to solve the problem?

Woocommerce product I am mentioning as wallpaper.

Below is wallpaper.dart file to getdata:

import 'package:flutter/material.dart';
import 'dart:async';
import '../model/wallpaper_model.dart';
import './home.dart';
import '../helper_services/helperservices.dart';

class WallpaperWidget extends StatefulWidget {
  const WallpaperWidget({Key? key}) : super(key: key);

  @override
  State<WallpaperWidget> createState() => _WallpaperWidgetState();
}

class _WallpaperWidgetState extends State<WallpaperWidget> {
  List<Products>? wallpapers;
  var isLoaded = false;

  @override
  void initState() {
    super.initState();
    getData(); // Call getData to fetch wallpapers when the widget is initialized
  }


  getData() async {
    wallpapers = await HelperService().getWallpapers();
    if (wallpapers != null) {
      setState(() {
        isLoaded = true;
      });
    }
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Visibility(
        visible: isLoaded,
        child: ListView.builder(
          itemCount: wallpapers?.length,
            itemBuilder: (context, index) {
              final wallpaper = wallpapers?[index];
              return ListTile(
                title: Text(wallpaper?.name ?? ''),
                // Display other properties of the wallpaper as needed.
              );
            }
        ),
        replacement: Center(
          child: CircularProgressIndicator(),
        ),
      ),
    );
  }
}

Below is helperservice.dart for API call:

import 'dart:convert';
import 'package:http/http.dart' as http;
import '../model/wallpaper_model.dart'; // Import the Products class from your product_model.dart file

class HelperService {
  final String consumerKey = ''; // Replace with your actual consumer key
  final String consumerSecret = ''; // Replace with your actual consumer secret

  Future<List<Products>> getWallpapers() async {
    final String url = 'https://my_site.in/wp-json/wc/v3/products';

    // Encode consumer key and secret to base64
    final String credentials = base64Encode(
      utf8.encode('$consumerKey:$consumerSecret'),
    );

    try {
      final response = await http.get(
        Uri.parse(url), // Removed the per_page query parameter
        headers: {
          'Authorization': 'Basic $credentials',
        },
      );

      if (response.statusCode == 200) {
        // If the request is successful, parse the response
        List<Products> products = productsFromJson(response.body);
        return products;
      } else {
        throw Exception('Failed to load products');
      }
    } catch (e) {
      print('Error: $e');
      throw Exception('Error: $e');
    }
  }
}

i tried most of the way to display the product


Solution

  • GetData is an async function. That means that it will takes time to being executed and the result is not immediately available (to make it short). So, when build function is executed, you don't have that data, yet. Even if you put the function in the initState function, the order of execution is: initState() -> build() -> "when have time getData()" (again, to make it simplier). This because flutter is single threaded. In order to show data without reloading it, just use FutureBuilder(), which builds a widget when the data you provide is loaded.

    class _WallpaperWidgetState extends State<WallpaperWidget> {
      List<Products>? wallpapers;
      var isLoaded = false;
      late Future<dynamic> _future; //The type should be the type you receive from getData()
    
      @override
      void initState() {
        super.initState();
        _future = getData(); 
      }
    
    
      getData() async {
        wallpapers = await HelperService().getWallpapers();
        if (wallpapers != null) {
          setState(() {
            isLoaded = true;
          });
        }
      }
    
    @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Visibility(
            visible: isLoaded,
    
           
            child : FutureBuilder<dynamic>( //edit type here too
        future: _future, //the future that is loading from getData() function
        builder: (context, snapshot) {
         if (snapshot.hasError) {
            children = <Widget>[
              const Icon(
                Icons.error_outline,
                color: Colors.red,
                size: 60,
              ),
              Padding(
                padding: const EdgeInsets.only(top: 16),
                child: Text('Error: ${snapshot.error}'),
              ),
            ];
          } else if (snapshot.connectionState == ConnectionState.waiting){ 
            children = const <Widget>[
              SizedBox(
                width: 60,
                height: 60,
                child: CircularProgressIndicator(),
              ),
              Padding(
                padding: EdgeInsets.only(top: 16),
                child: Text('Awaiting result...'),
              ),
            ];
          }
          return ListView.builder(
              itemCount: snapshot?.length,
                itemBuilder: (context, index) {
                  final wallpaper = snapshot?[index];
                  return ListTile(
                    title: Text(snapshot?.name ?? ''),
                    // Display other properties of the wallpaper as needed.
                  );
                }
    
    
     }
    

    You want something like that. You probably want to edit some things (im not on an editor right now).