1

I am still with my first bloc based app, adding features. While previously, I stored some of my page specific data with the bloc class, for the last feature, I now moved most variables into its repository. I already feared that the instance of calling the repository gets lost, afterwards, which now proved true.

Is there a proper, easy way to make the instance persistent?

I know of inherited widgets, however, I have not yet figured out how to implement this and my question around this unfortunately remained unanswered. It would be great, if someone could point me to some direction!

In general, my idea was to have the api dealing with local files and online data, the repository with frequently re-used data (session data, presented data etc) and helper variables within the bloc. So when the UI requests data, the bloc asks the repository which will either return a value stored in a variable or request a value from the api.

This is, how the strucuture basically looks like (hope I have not missed anything significant)

void main() async {
  final UserRepository userRepository = UserRepository(); // <===== userRepository initialized
  runApp(MyApp(userRepository: UserRepository()));
}

class MyApp extends StatelessWidget {
  MyApp({Key key, this.userRepository}) : assert(userRepository != null), super(key: key);
  final UserRepository userRepository;

  @override
  Widget build(BuildContext context) {
    return BlocProvider<UserBloc>(  <====== userBloc injection to top of widget tree 
      create: (_) => UserBloc(userRepository: userRepository)..add(AppStarted()),
      child: App(),
    );
  }
}
// =================================================== APP WITH ROUTES
class App extends StatelessWidget {
  App({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      routes: {
        '/': (_) => HomePage(),
        'feature 1': (_) => HomePage(),
      },
    );
  }
}
// =================================================== LANDING PAGE WITH MAIN MENU
class HomePage extends StatefulWidget {
  HomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>  { 
  @override
  Widget build(BuildContext context) {
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
    ]);
    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text('MathUup'),
      ),
      child: SafeArea(
        child: CupertinoButton(
          child: Text('Feature 1',
              onPressed: () => Navigator.pushNamed(context, 'feature 1'),
  ),)));
}}     
// =================================================== BLOC
class UserBloc extends Bloc<UserEvent, UserState> {
  UserBloc({this.userRepository}) : super(AppInitial());
  final UserRepository userRepository;
  ...
    
      final user = await userRepository.getActiveUserData(userId);
      final lastSessionData = await userRepository.getLastSession(userId);
  ...
}
// =================================================== REPOSITORY
class UserRepository {
  UserRepository();
  final UserApiClient achievementsApiClient = UserApiClient();
  final SessionsApiClient sessionsApiClient = SessionsApiClient();
  UserSession activeUserSession;
  User activeUserData;
  
  
  Future<String> getLastUserId() async {
    final lastUserId = await sessionsApiClient.getLastUserId();
    return lastUserId;
  }
  Future<UserSession> getActiveUser() async {
    if (activeUserSession == null) {
      activeUserSession = await sessionsApiClient.getLastUser();
    }
    return activeUserSession;
  }
}
  
  
w461
  • 2,168
  • 4
  • 14
  • 40
  • Technically, there is no reason why your repository cannot stay the same instance through the whole life of your application. Now, whether you have implemented it that way is anyone's guess. You will need to post code and maybe a specific error or a specific point where your instance is not the instance you expect it to be. – nvoigt Nov 11 '20 at 13:38
  • @nvoigt Thanks, I added the significant parts of the code. If this leaves anything open with regards to the repository implementation, please tell me what. Copying the whole code might be a bit confusing to find the bits and pieces – w461 Nov 11 '20 at 14:05
  • "I already feared that the instance of calling the repository gets lost, afterwards, which now proved true." How do you know? It looks good. – nvoigt Nov 11 '20 at 14:07
  • On start-up, I load data from local files and store it in a variable within the repository. Later on, I want to update the data of the local file. So I call again a function of the repository (which I forgot to copy in the example above), add the new data to the data loaded on start-up and overwrite the local file (json structure makes appending difficult). However, when storing, I find the variable local to the repository now empty. I checked that this variable is populated upon start-up. – w461 Nov 11 '20 at 14:19

1 Answers1

1

This line is creating and initializing your user repository:

final UserRepository userRepository = UserRepository(); // <===== userRepository initialized

However, this line is not passing that repository, it's creating a new repository, ignoring the one you just initialized:

runApp(MyApp(userRepository: UserRepository()));

I think you meant to use the variable you already have:

runApp(MyApp(userRepository: userRepository));
nvoigt
  • 75,013
  • 26
  • 93
  • 142
  • very good point. Unfortunately changing it to runApp(MyApp(userRepository: userRepository)) still does not provide me the value on the 2nd call. I have traced down the way of forwarding the instance and haven't found another flow. So I guess, it has to be some other issue. But very helpful now to rule out the instance as the issue. – w461 Nov 11 '20 at 14:44
  • You can use your IDE's feature of "find usages" and see if your set your variables to null at some point. – nvoigt Nov 11 '20 at 14:49
  • 1
    My appologies. This was indeed caused by incomplete test data which caused some funky behaviour – w461 Nov 11 '20 at 15:22