skip to Main Content

To make my point clear I have created this small code..

it looks like I missing to understand concept of byref and byval here..

and what does actually Get.put works.

I have commented the lines what made me confused

GetxController

class UserController extends GetxController  {
  List<UserModel> _userlist = [];

  UserModel? currentuser;


  UserController() {
     _userlist.add(UserModel(username: 'temp', password: 't123'));
  }

  List<UserModel> get getusers {
    return _userlist;
  }
}

this is main

void main()
{
  final uc1=Get.put(UserController());
  UserModel user1=UserModel(username: 'abc', password: 'a123');
  uc1.currentuser=user1;

  //showing print abc
  print(uc1.currentuser!.username);


  final uc2=Get.put(UserController());
  UserModel user2=UserModel(username: 'xyz', password: 'x123');
  uc2.currentuser=user2;

  //showing printing result=xyz
  print(uc2.currentuser!.username);

  //showing printing result=xyz, instead of abc why?
  print(uc1.currentuser!.username);

}

2

Answers


  1. Because you are using the put method two time
    if you want to update a single instance then follow the below code:

    void main()
    {
      final uc1=Get.put(UserController());
      UserModel user1=UserModel(username: 'abc', password: 'a123');
      uc1.currentuser=user1;
    
      //showing print abc
      print(uc1.currentuser!.username);
    
      UserController uc2 = Get.find();
      UserModel user2=UserModel(username: 'xyz', password: 'x123');
      uc2.currentuser=user2;
    
      //showing printing result=xyz
      print(uc2.currentuser!.username);
    
      //showing printing result=abc
      print(uc1.currentuser!.username);
    
    }
    
    Login or Signup to reply.
  2. Get.put only puts a new instance when there isn’t already one, (or the one that’s there is marked as dirty). You can see it by digging deeper into the code. Ctrl + clicking the put method (in Android Studio at least) makes you able to see the implementation. The first step leads to

      S put<S>(S dependency,
              {String? tag,
              bool permanent = false,
              InstanceBuilderCallback<S>? builder}) =>
          GetInstance().put<S>(dependency, tag: tag, permanent: permanent);
    

    then doing it on put again leads to

      S put<S>(
        S dependency, {
        String? tag,
        bool permanent = false,
        @deprecated InstanceBuilderCallback<S>? builder,
      }) {
        _insert(
            isSingleton: true,
            name: tag,
            permanent: permanent,
            builder: builder ?? (() => dependency));
        return find<S>(tag: tag);
      }
    

    And digging into the _insert method gives:

      /// Injects the Instance [S] builder into the `_singleton` HashMap.
      void _insert<S>({
        bool? isSingleton,
        String? name,
        bool permanent = false,
        required InstanceBuilderCallback<S> builder,
        bool fenix = false,
      }) {
        final key = _getKey(S, name);
    
        if (_singl.containsKey(key)) {
          final dep = _singl[key];
          if (dep != null && dep.isDirty) {
            _singl[key] = _InstanceBuilderFactory<S>(
              isSingleton,
              builder,
              permanent,
              false,
              fenix,
              name,
              lateRemove: dep as _InstanceBuilderFactory<S>,
            );
          }
        } else {
          _singl[key] = _InstanceBuilderFactory<S>(
            isSingleton,
            builder,
            permanent,
            false,
            fenix,
            name,
          );
        }
      }
    

    Here you can see that if it already exists and isDirty is true, or if it doesn’t exist yet, only then it inserts a new instance. Now I’m not entirely sure when isDirty is set, but I believe it happens when you change routes in your app. So the second time you call put you are actually retrieving the one that is already put there before. Now if you want to have multiple instances you can use Get.create(() => UserController()); followed by Get.find instead. Like:

    void main()
    {
      Get.create(() => UserController());
      UserController uc1 = Get.find();
      UserModel user1=UserModel(username: 'abc', password: 'a123');
      uc1.currentuser=user1;
    
      //showing print abc
      print(uc1.currentuser!.username);
    
    
      UserController uc2 = Get.find();
      UserModel user2=UserModel(username: 'xyz', password: 'x123');
      uc2.currentuser=user2;
    
      //showing printing result=xyz
      print(uc2.currentuser!.username);
    
      //showing printing result=abc
      print(uc1.currentuser!.username);
    
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search