Search code examples
flutterdartflutter-getx

Why are saved news not showing up?


I'm trying to implement the "Saved" page, where saved news will be displayed. News comes via API and is displayed in cards. And every news can be saved. Clicking on an icon will display it on a separate page. But now something is not working. Can you please help with implementation? I will be grateful for help)

Controller code that fires when the icon is clicked:

Widget customListTile(Article article, BuildContext context) {
  final newsController = Get.put(FavoritesController());
  ...
  IconButton(
             onPressed: () 
                         {
                          newsController.addNews(article);
                          },
                          icon: const Icon(Icons.favorite_border))
}


class FavoritesController extends GetxController {

  var _news = {}.obs;

  void addNews(Article article) {
    if(_news.containsKey(article)) {
      _news[article] += 1;
    } else {
      _news[article] = 1;
    }


   Get.snackbar("News added", "You have added the ${article.title}",
   snackPosition: SnackPosition.BOTTOM,
       duration: Duration(seconds: 2)
   );
  }

  get news => _news;
}

As well as the code of the output page itself. For now, I just want to display a picture of the added news there, but they do not appear there:

class FavNews extends StatelessWidget {
  final FavoritesController controller = Get.find();

  FavNews({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 600,
      child: ListView.builder(
          itemCount: controller.news.length,
          itemBuilder: (BuildContext context, int index) {
            return FavNewsItem(
              controller: controller,
              article: controller.news.keys.toList()[index],
              index: index,
            );
          }),
    );
  }
}


class FavNewsItem extends StatelessWidget {
  final FavoritesController controller;
  final Article article;
  final int index;

  const FavNewsItem({Key? key, required this.controller, required this.article, required this.index}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(padding: const EdgeInsets.symmetric(
      horizontal: 20.0,
      vertical: 10,
    ),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        Container(
          height: 200.0,
          width: double.infinity,
          decoration: BoxDecoration(
            image: DecorationImage(
                image: NetworkImage(article.urlToImage), fit: BoxFit.cover),
            borderRadius: BorderRadius.circular(12.0),
          ),
        ),
      ],
    ),
    );
  }
}

My Article model:

//Source model

class Source {
  String id;
  String name;

  Source({required this.id, required this.name});

  factory Source.fromJson(Map<String, dynamic> json) {
    return Source(id: json['id'], name: json['name']);
  }
}

// Article model 

import 'source_model.dart';

class Article {
  Source source;
  String author;
  String title;
  String description;
  String url;
  String urlToImage;
  String publishedAt;
  String content;

  Article(
      {required this.source,
      required this.author,
      required this.title,
      required this.description,
      required this.url,
      required this.urlToImage,
      required this.publishedAt,
      required this.content});


  factory Article.fromJson(Map<String, dynamic> json) {
    return Article(
      source: Source.fromJson(json['source']),
      author: json['author'] ?? "",
      title: json['title'] ?? "",
      description: json['description'] ?? "",
      url: json['url'] ?? "",
      urlToImage: json['urlToImage'] ?? "",
      publishedAt: json['publishedAt'] ?? "",
      content: json['content'] ?? "",
    );
  }
}


Solution

  • Refer getx_example for GetX controller.

    //// Wrap SizedBox with Obx widget.

    class FavNews extends StatelessWidget {
      final FavoritesController controller = Get.find();
    
      @override
      Widget build(BuildContext context) {
        return Obx(() {
          return SizedBox(
            height: 600,
            child: ListView.builder(
                itemCount: controller.news.length,
                itemBuilder: (BuildContext context, int index) {
                  return FavNewsItem(
                    article: controller.news.keys.toList()[index],
                    index: index,
                  );
                }),
          );
        });
      }
    }
    

    //// Remove double.infinity width from the Container.

    class FavNewsItem extends StatelessWidget {
      final Article article;
      final int index;
    
      FavNewsItem({required this.article, required this.index});
    
      @override
      Widget build(BuildContext context) {
        return Padding(
          padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Container(
                height: 200.0,
                width: 200.0,
                // width: double.infinity,
                decoration: BoxDecoration(
                  image: DecorationImage(
                      image: NetworkImage(article.urlToImage), fit: BoxFit.cover),
                  borderRadius: BorderRadius.circular(12.0),
                ),
              ),
            ],
          ),
        );
      }
    }