Flutter:my DropdownButton value is not taken? - flutter

my working with DropdownButton and i facing a problem my value is not taken
is show me null
my code is below
SizedBox(
height: 60.0,
child: new StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection("Category").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return new Text("Please wait");
var length = snapshot.data.documents.length;
DocumentSnapshot ds = snapshot.data.documents[length - 1];
return new DropdownButton(
items: snapshot.data.documents.map((
DocumentSnapshot document) {
return DropdownMenuItem(
child: new Text(document.data["name"]));
}).toList(),
value: category,
onChanged: (value) {
print(value);
},
hint: new Text("Category"),
style: TextStyle(color: Colors.black),
);
}
),
),

You should read more about StatefulWidget, here you have documentation: https://flutter.io/tutorials/interactive/
To fix your issue just update your category variable and refresh the state.
UPDATE
looks like you forget the value for the item also.
SizedBox(
height: 60.0,
child: new StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection("Category").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return new Text("Please wait");
var length = snapshot.data.documents.length;
DocumentSnapshot ds = snapshot.data.documents[length - 1];
return new DropdownButton(
items: snapshot.data.documents.map((
DocumentSnapshot document) {
return DropdownMenuItem(
value: document.data["name"],
child: new Text(document.data["name"]));
}).toList(),
value: category,
onChanged: (value) {
print(value);
setState(() {
category = value;
});
},
hint: new Text("Category"),
style: TextStyle(color: Colors.black),
);
}
),
),

Related

TextField value only updated when hovered

I have a Category TextField with a controller. The controller value is updated onChange of a Product Dropdown. What I expect is upon onChange the value of the categoryField should be updated. However, I can only see the update on the TextField once I hover on it.
Category TextField
var productCategory = Column(
children: [
TextField(
controller: categoryController,
enabled: false,
focusNode: categoryFocusNode,
),
const Padding(
padding: EdgeInsets.all(5.0), child: SizedBox(width: 200)),
],
);
Product Dropdown onChange
void onChange<Product>(prod) {
BlocProvider.of<InvoiceCubit>(context).updateProduct(prod);
categoryController.text = prod.category.categoryName.toString();
}
I have finally figured it out. Since I am using a rxdart stream, I created both the Product dropdown and Category on the StreamBuilder. Then I created the categoryController within the builder itself with text value from the product category. Below is my code:
var productDropdownField = StreamBuilder<Product>(
stream: BlocProvider.of<InvoiceCubit>(context).productStream,
builder: (context, snapshot) {
final categoryController = TextEditingController();
categoryController.text = snapshot.hasData
? snapshot.data!.category.categoryName
: "";
var productCategory = Column(
children: [
CustomTextField(
labelText: "Category",
controller: categoryController,
enabled: false,
),
const Padding(
padding: EdgeInsets.all(10.0),
child: SizedBox(width: 200)),
],
);
return StreamBuilder<Object>(
stream:
BlocProvider.of<InvoiceCubit>(context).priceStream,
builder: (context, snapshot) {
return Column(
children: [
BlocBuilder<ProductsCubit, ProductsState>(
builder: (context, state) {
if (state is ProductsLoaded) {
List<DropdownMenuItem<Product>>
dropDownItems = state.products
.map((e) => DropdownMenuItem<Product>(
value: e,
child: Text(
e.productName,
style: const TextStyle(
color: Colors.black,
fontWeight:
FontWeight.w900),
),
))
.toList();
if (invoiceItem == null &&
prodSelected == false) {
onChange<Product>(state.products.first);
prodSelected = true;
}
return CustomDropdown<Product>(
labelText: "Product",
value:
BlocProvider.of<InvoiceCubit>(context)
.getProduct(),
items: dropDownItems,
context: context,
onChanged: onChange,
);
}
return const SizedBox(
width: 100, child: Text("Error"));
},
),
productCategory,
],
);
});
});
categoryController won't be updated via onChange but will be updated based on the snapshot.data

I want to display document ids of collection in future builder but i got error

Below is the code in which i want to display documents ids from cloud firestore but i got error.
FutureBuilder<QuerySnapshot>(
future: db.collection('/Exam').get(),
builder:
(BuildContext context, AsyncSnapshot asyncSnapshot) {
if (asyncSnapshot.hasError)
return Text("Error: ${asyncSnapshot.error}");
if (!asyncSnapshot.hasData)
return const CircularProgressIndicator();
return DropdownButton<String>(
isExpanded: true,
items: asyncSnapshot.data!.docs
.map(
(snap) => DropdownMenuItem(
value: snap.id,
child: Text(
snap.id.toString(),
),
),
)
.toList(),
value: _selectedexam,
onChanged: (String? newValue) {
setState(() {
_selectedexam = newValue!;
_selectedsemester = null;
print(_selectedexam);
});
},
);
}),
Try adding the Generic type to the map<T>() method:
asyncSnapshot.data!.docs
.map<DropdownMenuItem<String>>(
(snap) => DropdownMenuItem<String>(
value: snap.id,
child: Text(
snap.id.toString(),
),
),
)
.toList(),

How to create a DropMenuItem from Future list in flutter?

I am getting a data from local database using floor in flutter.
And I want to display the list of doctors from the db I am using DropDownButton to do this
This is my code
DropdownButton(
icon: const Icon(
Icons.arrow_drop_down,
),
hint: const Text('Select a doctor'),
items: FutureBuilder<List<Doctor>>(
future: findAllDoctor(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return snapshot.data
.map((doctor) => DropdownMenuItem(
child: Text(doctor.name),
value: doctor,
))
.toList();
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
}
), ,
onChanged: (val) {
print(val);
},
),
And this is how I get the data
Future<List<Doctor>> findAllDoctor() async {
return await database.doctorDao.findAllDoctor();
}
I am getting this error
The argument type 'FutureBuilder<List<Doctor>>' can't be assigned to the parameter type 'List<DropdownMenuItem<Object>>?'.
What I need here is to display the doctors as list in a form to choose from.
Your FutureBuilder was placed in wrong place, check my edited code:
FutureBuilder<List<Doctor>>(
builder: (context, snapshot) {
if (snapshot.hasData) {
return DropdownButton<String>(
icon: const Icon(
Icons.arrow_drop_down,
),
hint: const Text('Select a doctor'),
items: snapshot.data
?.map((doctor) => DropdownMenuItem(
child: Text(doctor.name),
value: doctor.name,
))
.toList(),
onChanged: (val) {
print(val);
},
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return const CircularProgressIndicator();
},
);

How to add text on dropdownmenu?

I'm making an app using Flutter and I want to add text for my DropDownMenu like Select car make or something like that.
I could not find a tutorial so was hoping someone could help.
Here is my code:
new FormField(builder: (FormFieldState state) {
return InputDecorator(
decoration: InputDecoration(
),
child:FutureBuilder<Album>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
final album = snapshot.data;
final results = album.results;
return DropdownButtonHideUnderline(
child: DropdownButton<Results>(
isExpanded: true,
items: results.map((result) {
return DropdownMenuItem<Results>(
value: result,
child: Text('${result.modelName}'),
);
}).toList(),
onChanged: (album ) {
// selected album
setState(() {
_selected = album;
});
},
value: _selected,
));
} else
return CircularProgressIndicator();
}),
);
}),
I tried to set hinttext, but it does not work.
Here is how you can add a hint to your DropdownButton:
hint: Container(
width: 150,
child: Text(
"Select car",
style: TextStyle(color: Colors.grey),
textAlign: TextAlign.end,
),
),

How to build a dropdown in flutter from a future list

I am trying to make a dropdown select input in flutter! I want to get the data from a future list ref.
I am not sure how to go about it, as this gives me error :
Here is the code:
dropdownButtonHideUnderline(FormFieldState<String> state) {
return FutureBuilder(
future: Global.payCountriesRef.getData(),
builder: (BuildContext context, AsyncSnapshot snap) {
if (snap.hasData) {
List<PayCountries> countries = snap.data;
return new DropdownButtonHideUnderline(
child: new DropdownButton<String>(
value: _sendForm.country,
isDense: true,
onChanged: (String newValue) {
setState(() {
_sendForm.country = newValue;
//_updateDropdownValue(newValue, model);
state.didChange(newValue);
});
},
items: List<String>.from(countries)
.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList()
),
);
}
}
);
}
The code Below shows an example to populate a dropdown from a future list
new DropdownButtonHideUnderline(
child: new FutureBuilder<List<BranchItems>>(
future: new BranchService().fetchBranchItems(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return new Container();
} else if (snapshot.hasData) {
list.clear();
//listItemNames.clear();
dropDownItemsMap = new Map();
snapshot.data.forEach((branchItem) {
//listItemNames.add(branchItem.itemName);
int index = snapshot.data.indexOf(branchItem);
dropDownItemsMap[index] = branchItem;
list.add(new DropdownMenuItem(
child: new DropDownItem(
image: Image.network(branchItem.itemPicture),
text: branchItem.itemName),
value: index));
});
return DropdownButton(
items: list,
onChanged: (int selected) {
_selectedItem = list[selected].value;
setState(() {
selectedItemName =
dropDownItemsMap[_selectedItem].itemName;
});
},
hint: new Text(
selectedItemName,
style: new TextStyle(color: Colors.blue),
),
);
} else {
return CircularProgressIndicator();
}
},
),
),