8

I'm in the process of learning GetX state management and stumble upon the DropdownButton widget. How do I update the selected value with the selected value cannot be observed. Here is my DropdownButton widget

              DropdownButton(
                  hint: Text(
                    'Book Type',
                  ),
                  onChanged: (newValue) {
                    print(newValue);
                  },
                  value: selectedType,
                  items: bookController.listType.map((selectedType) {
                    return DropdownMenuItem(
                      child: new Text(
                        selectedType,
                      ),
                      value: selectedType,
                    );
                  }).toList(),
                ),

The

var selectedType;

declared in the widget build. I tried to make this variable observable but the layout throws an overflow error. I also wrap the widget with obx but still, it throws the same error. How do exactly this widget implement using GetX. I'm pulling my hair here. I can work with other widgets with getX.

Hanis
  • 309
  • 1
  • 6
  • 15

3 Answers3

9

First create your controller class.

class BookController extends GetxController {

   // It is mandatory initialize with one value from listType
   final selected = "some book type".obs;

   void setSelected(String value){
     selected.value = value;
   }

}

On the view, instantiate your Controller and wrap the DropdownButton with an Obx widget:

    BookController bookcontroller = BookController();
    
    Obx( () => DropdownButton(
                      hint: Text(
                        'Book Type',
                      ),
                      onChanged: (newValue) {
                        bookController.setSelected(newValue);
                      },
                      value: bookController.selected.value,
                      items: bookController.listType.map((selectedType) {
                        return DropdownMenuItem(
                          child: new Text(
                            selectedType,
                          ),
                          value: selectedType,
                        );
                      }).toList(),
                    )
),
Tony
  • 2,515
  • 14
  • 38
  • 71
djalmafreestyler
  • 1,703
  • 5
  • 21
  • 42
  • 3
    i get following error The following assertion was thrown building Obx(dirty, state: _ObxState#829ce): There should be exactly one item with [DropdownButton]'s value: . Either zero or 2 or more [DropdownMenuItem]s were detected with the same value 'package:flutter/src/material/dropdown.dart': Failed assertion: line 850 pos 15: 'items == null || items.isEmpty || value == null || items.where((DropdownMenuItem item) { – Arul Jul 18 '21 at 15:10
  • 1
    The "value:" parameter must be one of the List of values (items parameter) passed to the Dropdown or null so it shows the hint parameter value. – djalmafreestyler Jul 18 '21 at 16:26
  • 1
    Yeah i figured it out, is any chance we can default in value, like its empty filed. – Arul Jul 19 '21 at 04:46
2

if you don't want to use observable variable then wrap your dropdown with getBuilder and in onChange function just update your controller like

               onChanged: (newValue) {
                     bookController.currentDropdownValue=newValue;
                    bookController.update();
                  },

Example

//Controller
class HomeController extends GetxController {
 var selectedDrowpdown = 'abc';
 List dropdownText = ['abc', 'def', 'ghi'];
  }
    //dropdown button in Ui 
  DropdownButton(
    hint: Text(
      'Book Type',
    ),
    onChanged: (newValue) {
      homeController.selectedDrowpdown=newValue;
      homeController.update();
    },
    value: homeController.selectedDrowpdown,
    items: [
      for (var data in homeController.dropdownTextList)
        DropdownMenuItem(
          child: new Text(
            data,
          ),
          value: data,
        )
    ])
1
final selected = "".obs;

BookController bookcontroller = BookController();
    
Obx( () => DropdownButton(
                  hint: Text(
                    'Book Type',
                  ),
                  onChanged: (newValue) {
                    bookController.setSelected(newValue);
                  },
                  value: bookController.selected.value==""?null:bookController.selected.value,
                  items: bookController.listType.map((selectedType) {
                    return DropdownMenuItem(
                      child: new Text(
                        selectedType,
                      ),
                      value: selectedType,
                    );
                  }).toList(),
                )
),

Try this, this worked for me.

janw
  • 8,758
  • 11
  • 40
  • 62