Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

The state of my object is not stored properly

I want to mark my object as favorite.

I have a list of object <RobotAnimation> which is displayed in a ListView. The class have two fields: title and isFavorite. Marking an object as a favorite works, but there is a problem when it comes to storing that state. When I perform a search of all items, after selecting an item as favorite, my favorite items are not being remembered. It seems like the state is being discarded.

What can I do to fix this problem?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Here’s what’s going on:

video

Here’s my code:

class RobotAnimation {
  String title;
  bool isFavorite;

  RobotAnimation({required this.title, this.isFavorite = false});

  @override
  String toString() {
    return '{Title: $title, isFavortite: $isFavorite}';
  }
}

class Animations extends StatefulWidget {
  const Animations({super.key});

  @override
  State<Animations> createState() => _AnimationsState();
}

class _AnimationsState extends State<Animations> with TickerProviderStateMixin {
  late TabController _tabController;

  List<RobotAnimation> animations = [];
  List<RobotAnimation> favoriteAnimations = [];
  List<String> results = store.state.animations;
  List<String> defaultFavorites = [];

  List<RobotAnimation> getAnimationList(
      List<String> animations, List<String> favorites) {
    List<RobotAnimation> robotAnimations = [];
    for (var animation in animations) {
      bool isFav = false;
      for (var favorite in favorites) {
        if (favorite == animation) {
          isFav = true;
        }
      }
      robotAnimations.add(RobotAnimation(title: animation, isFavorite: isFav));
    }
    return robotAnimations;
  }

  List<RobotAnimation> filterFavorites() {
    List<RobotAnimation> filtered = favoriteAnimations;
    animations.where((element) => element.isFavorite == true).toList();

    return filtered;
  }

  void filterSearchResults(String query) {
    List<RobotAnimation> searchList =
        getAnimationList(results, defaultFavorites);
    log('query: $query');

    List<RobotAnimation> filteredList = searchList
        .where((element) =>
            element.title.toLowerCase().contains(query.toLowerCase()))
        .toList();

    log(searchList.toString());

    log(filteredList.toString());
    setState(() => animations = filteredList);
  }

  @override
  void initState() {
    animations = getAnimationList(results, defaultFavorites);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return StoreConnector<AppState, _Props>(
      converter: (store) => _mapStateToProps(store),
      builder: (_, props) {
        return Scaffold(
          body: TabBarView(
            ...
            children: [
              Container(
                padding: const EdgeInsets.all(8.0),
                child: Column(
                  children: [
                    TextField(
                      onChanged: filterSearchResults,
                      decoration: const InputDecoration(
                        labelText: 'Search',
                        hintText: 'Search animation',
                        prefixIcon: Icon(Icons.search),
                      ),
                    ),
                    Expanded(
                      child: ListView.separated(
                        itemCount: animations.length,
                        separatorBuilder: (context, index) => const Divider(),
                        itemBuilder: (context, index) {
                          return ListTile(
                            onTap: () {
                              props.socket?.animation(IAnimation(
                                  animation: animations[index].title));
                            },
                            title: ExtendedText(
                              animations[index].title,
                              maxLines: 1,
                              overflowWidget: const TextOverflowWidget(
                                position: TextOverflowPosition.middle,
                                align: TextOverflowAlign.center,
                                child: Text(
                                  '...',
                                  overflow: TextOverflow.ellipsis,
                                ),
                              ),
                            ),
                            trailing: Row(
                              mainAxisSize: MainAxisSize.min,
                              children: [
                                IconButton(
                                  onPressed: () {
                                    setState(() {
                                      animations[index].isFavorite
                                          ? animations[index].isFavorite = false
                                          : animations[index].isFavorite = true;
                                    });
                                  },
                                  icon: animations[index].isFavorite
                                      ? Icon(
                                          Icons.favorite,
                                          color: Colors.red.shade500,
                                        )
                                      : Icon(
                                          Icons.favorite_border,
                                          color: Colors.grey.shade500,
                                        ),
                                ),
                              ],
                            ),
                          );
                        },
                      ),
                    )
                  ],
                ),
              ),
            ],
          ),
        );
      },
    );
  }
}

class _Props {
  final Connection? socket;
  final List<String> animations;

  _Props({
    required this.socket,
    required this.animations,
  });
}

_Props _mapStateToProps(Store<AppState> store) {
  return _Props(
    socket: store.state.socket,
    animations: store.state.animations,
  );
}

>Solution :

Try this inside your IconButton onPressed-Method:

setState(() {
  if (animations[index].isFavorite) {
    animations[index].isFavorite = false
    defaultFavorites.remove(animations[index].title)
  } else {
    animations[index].isFavorite = true;
    defaultFavorites.add(animations[index].title)
  }
});

It seems like you always generate a new list of animations based on the two lists List<String>.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading