databasestringflutterdynamic-listsqflite

How to build a list of dynamic strings in Flutter?


I'm coding an app/game where user inputs his own rules on textfields stored in a SQFLite database.

Rules are related to a friend, so it's in a class Friend, with an id, name, rule0, rule1, rule2...rule9. Which is REALLY annoying for a lot of reasons, but I think I need it to be in Friend class so it get stored with the right friend.id.

I got the obvious error 'only static members can be accessed on initializers' when i try List<Strings> rules = [rule0, rule1]; or List<dynamic> rules = [...];

Does anyone knows how I could fix this ? Create a new class Rules and each rule has ID related to the right friend ? Or if I can just create a dynamic list whithin Friend ?

Really lost on this. Any help is welcome.

class Friend {

  int id;
  String name;
  String pic;
  bool play;
  String rule0;
  String rule1;
  String rule2;
  String rule3;
  String rule4;
  String rule5;
  String rule6;
  String rule7;
  String rule8;
  String rule9;

  Friend();

  // i have then a fromMap() and a toMap() for the database

}

Solution

  • I'm not completely sure, but it seems like you're having trouble with both the SQL aspect as well as the class representation of your data.

    If you know for sure there will only be a set number of rules, you could approach it in the way you currently have. The addition I'd do is to make a 'getter' function for the list of rules i.e.

    List<String> get rules => [rule1, rule2, rule2, ...].where((item) => item != null).toList()
    

    Note that if you were using a constructor, you could instead build the list in the constructor as follows:

    class Friend {
      int id;
      String name;
      String pic;
      bool play;
      String rule0;
      String rule1;
      String rule2;
      String rule3;
      String rule4;
      String rule5;
      String rule6;
      String rule7;
      String rule8;
      String rule9;
    
      List<String> rules;
    
      Friend(
          {this.id,
          this.name,
          this.pic,
          this.play,
          this.rule0,
          this.rule1,
          this.rule2,
          this.rule3,
          this.rule4,
          this.rule5,
          this.rule6,
          this.rule7,
          this.rule8,
          this.rule9})
          : rules = [
              rule0,
              rule1,
              rule2,
              rule3,
              rule4,
              rule5,
              rule6,
              rule7,
              rule8,
              rule9,
            ].where((item) => item != null).toList(growable: false);
    }
    

    I wouldn't recommend that though (or if you do, you should probably be making either rule* or rules private or maintaining state somehow). The list of strings doesn't store references to the rule0, rule1, ... strings but rather stores the strings themselves. You could get around this by making a Rule class and making rule0-9 final, but that's getting a bit complicated.


    It most likely makes more sense for this to be a dynamic list of items. SQL doesn't handle that, so you're going to have to make a separate table for rules.

    You'll have two tables something like this, where id are both PRIMARY KEYs and friendId is a FOREIGN KEY:

    Friend(id, name, pic, play) and Rule(id, friendId, text)

    Saving and updating will become more complicated now. You'll have to be more careful about maintaining the list of rules in the database, but it isn't all that difficult. If you know that you'll only be writing to the list from one location (i.e. one class), you could keep the difference between what the class's current state and the initial state were, but realistically unless you're dealing with 10's of thousands of rules, it probably won't matter appreciably.