skip to Main Content

i want return type of this method bool and depende on i rendered the UI

global variable bool checkFav = false;
on every Page View i want to call this method for appearing the favourite icon

 Future<bool?> checkFavourite(int id) async {
    final url = Uri.parse('https://quotes.limpidsol.com/api/favourite');
    var pref = await SharedPreferences.getInstance();
    final response = await http.post(
      url,
      body: {'qoute_id': id.toString()},
      headers: {"Authorization": "Bearer ${pref.getString('token')}"},
    );
    if (response.statusCode == 200) {
      final Map<String, dynamic> responseData = jsonDecode(response.body);
      String message = responseData['message'];
      if (message == 'Qoute favourite successfully') {
        print('ok');
        return true;
      }
    }
    return null;
  }

method call in pageView::>>
checkFav = checkFavourite(quote_id) as bool;

depending the returning value of future (true/ false)
i updating the UI without loading

 IconButton(
                            onPressed: () {
                              checkFav
                                  ? handleRemoveToFav(quoteList[index]['id'])
                                  : handleAddToFav(quoteList[index]['id']);
                            },
                            icon: Icon(
                              checkFav
                                  ? Icons.favorite_outlined
                                  : Icons.favorite_border,
                              color: checkFav ? Colors.red : Colors.grey,
                              size: 30.0,
                            ),
                          ),

FutureBuilder return something widget or progressIndicator but scanrio is different please view the picture
please view picture

3

Answers


  1. Chosen as BEST ANSWER

    checkFavourite add/remove methods

    ` Widget build(BuildContext context) { return Scaffold( body: _isLoading ? const Center( child: CircularProgressIndicator(), ) : PageView.builder( scrollDirection: Axis.vertical, itemBuilder: (context, index) { List likesList = quoteList[index]['likes']; int quote_id = quoteList[index]['id'];

                  <<<here i call method on every pageView>>>
    
                  checkFav = await checkFavourite(quote_id) as bool;  
    
                String getCleanQuote() {
                  // Remove HTML tags and entities from the quote text
                  RegExp exp = RegExp(r"<[^>]*>|&[^;]+;",
                      multiLine: true, caseSensitive: true);
                  return quoteList[index]['qoute'].replaceAll(exp, '');
                }
    
                return Stack(
                  children: [
                    Center(
                      child: Text(
                        getCleanQuote(),
                        textAlign: TextAlign.center,
                        style: const TextStyle(
                            fontSize: 20, fontFamily: 'Poppins'),
                      ),
                    ),
                    Positioned(
                      top: MediaQuery.of(context).size.height * 0.63,
                      // left: MediaQuery.of(context).size.width * 0.81,
                      right: 0,
                      bottom: 0,
                      child: Column(
                        children: [
                          Container(
                            height: 32.0,
                            child: IconButton(
                              onPressed: () {
                                setState(() {
                                  detectId =
                                      !detectId; // Toggle the local state
                                  if (detectId) {
                                    likesList.add({
                                      'qoute_id':
                                          quoteList[index]['id'].toString()
                                    });
                                  } else {
                                    likesList.removeWhere((item) =>
                                        item['qoute_id'] ==
                                        quoteList[index]['id'].toString());
                                  }
                                });
    
                                likeUnlikeDetectId
                                    ? handleLikeOrUnlike(quoteList[index]['id'],
                                        'unlike', context)
                                    : handleLikeOrUnlike(quoteList[index]['id'],
                                        'like', context);
                              },
                              icon: Icon(
                                  likeUnlikeDetectId
                                      ? Icons.thumb_up
                                      : Icons.thumb_up_alt_outlined,
                                  color: likeUnlikeDetectId
                                      ? Colors.blueAccent
                                      : Colors.grey),
                            ),
                          ),
                          Text(likesList.length.toString()),
                          
    

    <>

    IconButton( onPressed: () { checkFav ? handleRemoveToFav(quoteList[index]['id']) : handleAddToFav(quoteList[index]['id']); }, icon: Icon( checkFav ? Icons.favorite_outlined : Icons.favorite_border, color: checkFav ? Colors.red : Colors.grey, size: 30.0, ), ),

    `


  2. Since your method returns a Future, you must await it. So you need to do checkFav = await checkFavourite(quote_id) instead of checkFav = checkFavourite(quote_id) as bool

    Login or Signup to reply.
  3. You can use a FutureBuilder to show a gray favorite icon until the checkFavourite method completes, and then based on the returned result you will show gray or red icon.

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      Future<bool> checkFavourite(int id) async {
        await Future.delayed(const Duration(seconds: 1));
        
        // always return true or false
        return true;
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            body: Center(
              child: FutureBuilder<bool>(
                future: checkFavourite(1),
                builder: (context, snapshot) {
                  var checkFav = false;
                  if (snapshot.hasData) {
                    checkFav = snapshot.data!;
                  } else if (snapshot.hasError) {
                    checkFav = false;
                  }
    
                  return Icon(
                    checkFav ? Icons.favorite_outlined : Icons.favorite_border,
                    color: checkFav ? Colors.red : Colors.grey,
                    size: 30.0,
                  );
                },
              ),
            ),
          ),
        );
      }
    }
    

    If you are not OK, with this approach, because of the icon "blink", you can delay the render of the whole build method until you fetch the favorite state.
    You can show a CircularProgressIndicator, until data is loaded, then show your widgets

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatefulWidget {
      const MyApp({super.key});
    
      @override
      State<MyApp> createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      bool _loadingResources = true;
      bool _checkFav = false;
    
      @override
      void initState() {
        super.initState();
        checkFavourite(1);
      }
    
      Future<void> checkFavourite(int id) async {
        await Future.delayed(const Duration(seconds: 1));
        final checkFav = true; // get it from the db.
    
        setState(() {
          _loadingResources = false;
          _checkFav = checkFav;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            body: Center(
              child: _loadingResources
                  ? CircularProgressIndicator()
                  : Icon(
                      _checkFav ? Icons.favorite_outlined : Icons.favorite_border,
                      color: _checkFav ? Colors.red : Colors.grey,
                      size: 30.0,
                    ),
            ),
          ),
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search