Home > Blockchain >  How can change my hardcoded data of a card carousel to dynamic data from api response -Flutter
How can change my hardcoded data of a card carousel to dynamic data from api response -Flutter

Time:10-13

Good day. Please I am have a challenge on how to change my hardcoded data to dynamic from the api. The response to the API returns success but populating the card carousel is the challenge I am having. I keep on getting error "type 'List' is not a subtype of type 'List<Map<String, String>>'"'

This my Api request:

  SharedPreferences _prefs;

  void getCategories() async {

    try {
      _prefs = await SharedPreferences.getInstance();
      var _categoryService = CategoryService();
      var result =
          await _categoryService.getCategories(_prefs.getString('token'));
      var categories = json.decode(result.body);

      print('categories');
      print(categories);

      List<Map<String, String>> foodCategories = categories;

    } catch (e) {
      throw Exception();
    }
  }

This is my list variable with hard coded data:

 final List<Map<String, String>> foodCategories = [
    {
      'name': 'Rice Planting',
      'image': 'images/Icon-001.png',
    },
    {
      'name': 'Harvesting',
      'image': 'images/Icon-002.png',
    },
    {
      'name': 'Machineries',
      'image': 'images/Icon-003.png',
    },
    {
      'name': 'Rice Products',
      'image': 'images/Icon-004.png',
    }
  ];

And this is my screen:

  Container(
              height: 105,
              margin: const EdgeInsets.only(
                top: 20.0,
                bottom: 25.0,
              ),
              child: ListView.builder(
                  scrollDirection: Axis.horizontal,
                  padding: const EdgeInsets.only(
                    left: 20.0,
                  ),
                  itemCount: this.foodOptions.length,
                  itemBuilder: (context, index) {
                    Map<String, String> option = this.foodOptions[index];
                    return Container(
                      margin: const EdgeInsets.only(right: 35.0),
                      child: Column(
                        children: <Widget>[
                          Container(
                            width: 70,
                            height: 70,
                            margin: const EdgeInsets.only(bottom: 10.0),
                            decoration: BoxDecoration(
                              borderRadius: BorderRadius.all(
                                Radius.circular(5.0),
                              ),
                              image: DecorationImage(
                                image: AssetImage(
                                  option['image'],
                                ),
                              ),
                              boxShadow: [
                                BoxShadow(
                                  blurRadius: 10.0,
                                  color: Colors.grey[300],
                                  offset: Offset(6.0, 6.0),
                                )
                              ],
                            ),
                          ),
                          Text(
                            option['name'],
                            style: TextStyle(fontSize: 17.0),
                          ),
                        ],
                      ),
                    );
                  }),
            ),
          

My basic challenge is how to switch this hardcoded data of **foodCategories ** to

 var categories = json.decode(result.body); which is from the API. any suggestion I will highly appreciate. The Api returns a json with image and category name

this is the UI picture

enter image description here

CodePudding user response:

Declare this List in your screen widget:

final List<Map<String, String>> foodCategories = [
    {
      'name': 'Rice Planting',
      'image': 'images/Icon-001.png',
    },
    {
      'name': 'Harvesting',
      'image': 'images/Icon-002.png',
    },
    {
      'name': 'Machineries',
      'image': 'images/Icon-003.png',
    },
    {
      'name': 'Rice Products',
      'image': 'images/Icon-004.png',
    }
  ];

Add this method to your screen widget:

void getCategories() async {

    try {
      _prefs = await SharedPreferences.getInstance();
      var _categoryService = CategoryService();
      var result =
          await _categoryService.getCategories(_prefs.getString('token'));
      var categories = json.decode(result.body);

      print('categories');
      print(categories);

      setState(() {
          foodCategories = categories;
      });
      

    } catch (e) {
      throw Exception();
    }
  }

and call the method in initState:

@override
  void initState() {
    super.initState();
getCategories();
  }

CodePudding user response:

You can use a state management tool for this use case, like Provider, on flutter.dev there is a nice explanation on how to use it Simple app state management.

Basically you wrap the api call inside a provider class and every time data comes from the api it notify the consumers that are using the provider.

  • Related