Home > Net >  Variable unexpectedly returning null in Flutter
Variable unexpectedly returning null in Flutter

Time:03-08

I am iterating through a list to get an item which has bool value false.

Class:

class Words {
  String alphabet;
  String word;
  String wordtype;
  String image;
  bool used;

  Words({
    required this.alphabet,
    required this.word,
    required this.wordtype,
    required this.image,
    required this.used,
  });
}

Following is the sample data being used

List<Words> initData = [
    Words(
        alphabet: 'a',
        word: 'apple',
        wordtype: 'fruit',
        image: 'assets/res/apple.jpg',
        used: false),
    Words(
        alphabet: 'a',
        word: 'ant',
        wordtype: 'insect',
        image: 'assets/res/ant.jpg',
        used: false),
    Words(
        alphabet: 'a',
        word: 'axe',
        wordtype: 'object',
        image: 'assets/res/axe.jpg',
        used: false),
    Words(
        alphabet: 'a',
        word: 'arrow',
        wordtype: 'object',
        image: 'assets/res/arrow.jpg',
        used: false),
    Words(
        alphabet: 'a',
        word: 'airplane',
        wordtype: 'object',
        image: 'assets/res/airplane.jpg',
        used: false),
    Words(
        alphabet: 'a',
        word: 'anchor',
        wordtype: 'object',
        image: 'assets/res/anchor.jpg',
        used: false),
    Words(
        alphabet: 'a',
        word: 'alligator',
        wordtype: 'animal',
        image: 'assets/res/alligator.jpg',
        used: false),
  ];

Calling Widget

class WordsWidget extends StatelessWidget {
  final homeCtrl = Get.find<HomeController>();
  WordsWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    print(homeCtrl.nextWord());
    return Container();
  }
}

Following function iterates, if all words have been used it resets them and iterates again.

Functions:

  nextWord() {
    Words nextword =
        Words(alphabet: '', word: '', wordtype: '', image: '', used: false);
    bool found = false;
    for (var i = 0; i < words.length; i  ) {
      if (words[i].used == false && found != true) {
        nextword = words[i];
        words[i].used = true;
        found = true;
      }
    }
    if (found == false) {
      print("resetting");
      resetWords();
    } else {
      print("Found = true so now returning");
      print(nextword.word);
      return nextword.word;
    }
  }

  void resetWords() {
    for (var a = 0; a < words.length; a  ) {
      words[a].used = false;
    }
    nextWord();
  }

The above works fine till it resets. After reset even though print above return shows the value but when I print the same on calling widget it returns null. Following is the output to illustrate the issue.

flutter: Found = true so now returning
2    flutter: arrow
flutter: Found = true so now returning
2    flutter: airplane
flutter: Found = true so now returning
2    flutter: anchor
flutter: Found = true so now returning
2    flutter: alligator
flutter: resetting
flutter: Found = true so now returning
flutter: apple
flutter: null

As you can see from above, after the word alligator it resets it self and sets used = false for all words. It then searches for the next word in iteration and it has found the word apple but the widget which called the function still returns null.

I would appreciate if someone could highlight what I am doing wrong. Thank you.

CodePudding user response:

There are two main issues with your current code

  1. It will run into an infinite recursion (and thus an exception) if your list of words is empty.

  2. In case, you didn't find a usable word in your for loop you don't return anything ...

nextWord() {

  // if there are no available words, don't need to do anything
  if (words.length == 0) {
    return null;
  }

  for (int i = 0; i < words.length; i  ) {
    //when you found an unused word, set the flag and return the word
    if (!words[i].used) {
      words[i].used = true;
      return words[i].word;
    }
  }

  //in case you didn't find anything, return the result of resetWords
  return resetWords();
}


resetWords() {
  //reset the flags
  for (int i = 0; i < words.length; i  ) {
    words[i].used = false;
  }

  //and call nextWord again, and return its result
  return nextWord();
}
  • Related