Shreyansh Sharma
Shreyansh Sharma

Reputation: 1824

Why my value is not updating in GetX Flutter

I made two very simple pages in GetX for learning it. I created three variabes for it, one is counter and other is destination and departure cities. The counter variable is updating perfectly, while the other variables are not changing their values. They only change when I hot reload.

If you think I have missed something or this doubt is very common and you have seen a very similar example like mine, please share it's link or correct the code if you can.

Here is my class:

import 'package:get/get.dart';

class Controller extends GetxController {
  var count = 0.obs;
  var des = "Delhi".obs;
  var dep = "Agra".obs;
  void increment() {
    count.value++;
    update();
  }

  void updateDes(String input) {
    des = input.obs;
  }

  void updateDep(String input) {
    dep = input.obs;
  }
}

Here is the first Page (you may check out lines 14, 30-52) -

import 'package:flutter/material.dart';
import 'package:flutter_application_firebase_noti_basics/my_controller.dart';
import 'package:flutter_application_firebase_noti_basics/new_home.dart';
import 'package:get/get.dart';

class Sample extends StatefulWidget {
  const Sample({Key? key}) : super(key: key);

  @override
  _SampleState createState() => _SampleState();
}

class _SampleState extends State<Sample> {
  final my_controller = Get.put(Controller());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: EdgeInsets.all(20.0),
        child: Center(
          child: Container(
            width: 300,
            height: 300,
            color: Colors.grey[400],
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Obx(
                  () => InkWell(
                    child: Text("${my_controller.des}"),
                    onTap: () {
                      Get.to(NewHome(
                        num: 1,
                      ));
                    },
                  ),
                ),
                const SizedBox(
                  height: 20,
                ),
                Obx(
                  () => InkWell(
                    child: Text('${my_controller.dep}'),
                    onTap: () {
                      Get.to(NewHome(
                        num: 2,
                      ));
                    },
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Here is the city selection page (you may want to check out lines: 32, 93-103, 121-125)-

import 'package:flutter/material.dart';
import 'package:get/get.dart';

import 'my_controller.dart';

class NewHome extends StatefulWidget {
  int? num = 0;

  NewHome({
    Key? key,
    this.num,
  }) : super(key: key);

  @override
  _NewHomeState createState() => _NewHomeState();
}

class _NewHomeState extends State<NewHome> {
  final List<Map<String, dynamic>> _allCities = [
    {"id": 1, "city": "Delhi", "state": ""},
    {"id": 2, "city": "Agra", "state": "UP"},
    {"id": 3, "city": "Mumbai", "state": "Maharashtra"},
    {"id": 4, "city": "Jaipur", "state": "Rajasthan"},
    {"id": 5, "city": "Jodhpur", "state": "Rajasthan"},
    {"id": 6, "city": "Ranchi", "state": "Jharkhand"},
    {"id": 7, "city": "Dhanbad", "state": "Jharkhand"},
    {"id": 8, "city": "Kanpur", "state": "UP"},
    {"id": 9, "city": "Chandigarh", "state": "Punjab"},
    {"id": 10, "city": "Meerut", "state": "UP"},
  ];

  final controller = Get.put(Controller());

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        backgroundColor: const Color(0xffEEEDEF),
        body: Column(
          children: [
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 10.0),
              child: Row(
                children: [
                  IconButton(
                    icon: const Icon(Icons.arrow_back),
                    color: Colors.orange,
                    onPressed: () {
                      Navigator.pop(context);
                    },
                  ),
                  Container(
                    width: MediaQuery.of(context).size.width * 0.85,
                    height: 50.0,
                    decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius:
                            const BorderRadius.all(Radius.circular(5.0)),
                        border: Border.all(color: Colors.blueAccent)),
                    child: TextField(
                      decoration: InputDecoration(
                        hintText: "Enter Origin",
                        border: InputBorder.none,
                        contentPadding: const EdgeInsets.only(left: 10.0),
                        hintStyle: TextStyle(
                          fontSize: 15.0,
                          color: Colors.grey[500],
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
            Align(
              alignment: Alignment.centerLeft,
              child: Padding(
                padding: EdgeInsets.only(
                    left: MediaQuery.of(context).size.width * 0.04, top: 3.0),
                child: Text(
                  'Popular Searches:',
                  style: TextStyle(
                      color: Colors.grey[500],
                      fontSize: MediaQuery.of(context).size.width * 0.035),
                ),
              ),
            ),
            Expanded(
              child: ListView.builder(
                itemCount: _allCities.length,
                itemBuilder: (context, index) {
                  return InkWell(
                    onTap: () {
                      controller.increment();
                      if (widget.num == 1) {
                        controller.updateDes(_allCities[index]['city']);
                        Get.back();
                      } else if (widget.num == 2) {
                        controller.updateDep(_allCities[index]['city']);
                        Get.back();
                      } else {
                        Get.back();
                      }
                    },
                    child: Padding(
                      padding: const EdgeInsets.only(
                          left: 18.0, top: 10.0, bottom: 15.0),
                      child: Text(
                        _allCities[index]['city'],
                        style: const TextStyle(
                          color: Colors.black,
                          fontSize: 15.0,
                          fontWeight: FontWeight.normal,
                        ),
                      ),
                    ),
                  );
                },
              ),
            ),
            Obx(
              () => Text("${controller.count} cities are selected",
                  style: const TextStyle(fontSize: 20.0)),
            )
          ],
        ),
      ),
    );
  }
}

Upvotes: 2

Views: 7759

Answers (3)

Chandan Pradhan
Chandan Pradhan

Reputation: 60

    import 'package:get/get.dart';

class Controller extends GetxController {
  var count = 0.obs;
  var des = "Delhi".obs;
  var dep = "Agra".obs;
  void increment() {
    count.value++;
    
  }

  void updateDes(String input) {
    des = input.obs;
  }

  void updateDep(String input) {
    dep = input.obs;
  }
}

In your first page code you need to remove updated() function because if you are using obs then no need to use update().

   import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    import 'my_controller.dart';
    
    class NewHome extends StatefulWidget {
      int? num = 0;
    
      NewHome({
        Key? key,
        this.num,
      }) : super(key: key);
    
      @override
      _NewHomeState createState() => _NewHomeState();
    }
    
    class _NewHomeState extends State<NewHome> {
      final List<Map<String, dynamic>> _allCities = [
        {"id": 1, "city": "Delhi", "state": ""},
        {"id": 2, "city": "Agra", "state": "UP"},
        {"id": 3, "city": "Mumbai", "state": "Maharashtra"},
        {"id": 4, "city": "Jaipur", "state": "Rajasthan"},
        {"id": 5, "city": "Jodhpur", "state": "Rajasthan"},
        {"id": 6, "city": "Ranchi", "state": "Jharkhand"},
        {"id": 7, "city": "Dhanbad", "state": "Jharkhand"},
        {"id": 8, "city": "Kanpur", "state": "UP"},
        {"id": 9, "city": "Chandigarh", "state": "Punjab"},
        {"id": 10, "city": "Meerut", "state": "UP"},
      ];
    
     
    
      @override
      Widget build(BuildContext context) {
      Get.lazyPut(() => Controller());// this line you need to add in your second file
        return SafeArea(
          child: Scaffold(
            backgroundColor: const Color(0xffEEEDEF),
            body: Column(
              children: [
                Padding(
                  padding: const EdgeInsets.symmetric(vertical: 10.0),
                  child: Row(
                    children: [
                      IconButton(
                        icon: const Icon(Icons.arrow_back),
                        color: Colors.orange,
                        onPressed: () {
                          Navigator.pop(context);
                        },
                      ),
                      Container(
                        width: MediaQuery.of(context).size.width * 0.85,
                        height: 50.0,
                        decoration: BoxDecoration(
                            color: Colors.white,
                            borderRadius:
                                const BorderRadius.all(Radius.circular(5.0)),
                            border: Border.all(color: Colors.blueAccent)),
                        child: TextField(
                          decoration: InputDecoration(
                            hintText: "Enter Origin",
                            border: InputBorder.none,
                            contentPadding: const EdgeInsets.only(left: 10.0),
                            hintStyle: TextStyle(
                              fontSize: 15.0,
                              color: Colors.grey[500],
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
                Align(
                  alignment: Alignment.centerLeft,
                  child: Padding(
                    padding: EdgeInsets.only(
                        left: MediaQuery.of(context).size.width * 0.04, top: 3.0),
                    child: Text(
                      'Popular Searches:',
                      style: TextStyle(
                          color: Colors.grey[500],
                          fontSize: MediaQuery.of(context).size.width * 0.035),
                    ),
                  ),
                ),
                Expanded(
                  child: ListView.builder(
                    itemCount: _allCities.length,
                    itemBuilder: (context, index) {
                      return InkWell(
                        onTap: () {
                          controller.increment();
                          if (widget.num == 1) {
                            controller.updateDes(_allCities[index]['city']);
                            Get.back();
                          } else if (widget.num == 2) {
                            controller.updateDep(_allCities[index]['city']);
                            Get.back();
                          } else {
                            Get.back();
                          }
                        },
                        child: Padding(
                          padding: const EdgeInsets.only(
                              left: 18.0, top: 10.0, bottom: 15.0),
                          child: Text(
                            _allCities[index]['city'],
                            style: const TextStyle(
                              color: Colors.black,
                              fontSize: 15.0,
                              fontWeight: FontWeight.normal,
                            ),
                          ),
                        ),
                      );
                    },
                  ),
                ),
                Obx(
                  () => Text("${controller.count.value} cities are selected",
                      style: const TextStyle(fontSize: 20.0)),
                )
              ],
            ),
          ),
        );
      }
    }

Kindly check this second page code i did some correction now may it will work fine.

Now in third page according to the second page you can change.

Main Thing about Get-X Statemanagment:-

  1. If you are using obx then no need to use update() function.
  2. when you'll access any member variable's value then you need to use .value. like controller.count.value.
  3. You need to add this line in any screen where you want to use GetX controller class:- Get.lazyPut(() => Controller()); this line will be add before Scaffold return statement.
  4. Wrap with Obx() only that widget in which you want to add observation.

Upvotes: 0

Jawad Fadel
Jawad Fadel

Reputation: 830

You need to remove update from your code and .obs from string value like this:

import 'package:get/get.dart';

class Controller extends GetxController {
  var count = 0.obs;
  var des = "Delhi".obs;
  var dep = "Agra".obs;
  void increment() {
    count.value++;
 // remove this --->   update();
  }

  void updateDes(String input) {
des=input
  // remove this--->  des = input.obs;

  }

  void updateDep(String input) {
   // remove this--->    dep = input.obs;
dep=input
  }
}

Upvotes: 0

developerjamiu
developerjamiu

Reputation: 654

That's because you're not updating the values properly. When using reactive (obs) variables, you're expected to update the value property of the variable.

Also you should not use update with obs variables as they will be automatically updated. So your controller will be:

class Controller extends GetxController {
  var count = 0.obs;
  var des = "Delhi".obs;
  var dep = "Agra".obs;

  void increment() {
    count.value++;
    // removed update()
  }

  void updateDes(String input) {
    // changing from des = input.obs
    des.value = input;
  }

  void updateDep(String input) {
    // changing from dep = input.obs
    dep.value = input;
  }
}

Upvotes: 7

Related Questions