Reputation: 3384
Im trying to get data from database and transmit that data to screen using stream.
I done this using FutureBuilder
that solution is working as spectated , but i need to use streambuilder
Can anyone help me to find the issue.
I have a method that get data from database
Future<List<CementSandAggregateView>> getAllRatios() async{
List<CementSandAggregateView> ratioList = new List();
var types = await ratioRepository.getAll();
for(int i = 0 ; i < types.length ; i ++){
CementSandAggregateView view = new CementSandAggregateView();
String cementRatio = types[i].cement.floor() < types[i].cement ? types[i].cement.toStringAsFixed(1):types[i].cement.toStringAsFixed(0);
String sandRatio = types[i].sand.floor() < types[i].sand ? types[i].sand.toStringAsFixed(1):types[i].sand.toStringAsFixed(0);
String aggregateRatio = types[i].aggregate.floor() < types[i].aggregate ? types[i].aggregate.toStringAsFixed(1):types[i].aggregate.toStringAsFixed(0);
view.ratio = "$cementRatio:$sandRatio:$aggregateRatio (${types[i].name})";
view.id = types[i].id;
view.name = types[i].name;
print(view.ratio);
ratioList.add(view);
}
return ratioList;
}
and i want to send this data using stream
class CementSandAggregateMixBloC {
BehaviorSubject<Future<List<CementSandAggregateView>>> _cSAMixController;
BLoCProvider provider;
CementSandAggregateMixBloC(){
provider = new BLoCProvider();
_cSAMixController = new BehaviorSubject<Future<List<CementSandAggregateView>>>();
_cSAMixController.add(provider.getAllRatios());
}
Observable<Future<List<CementSandAggregateView>>> inputObservable() => _cSAMixController.stream;
void dispose() {
_cSAMixController.close();
}
}
in my screen i use stream using streambuilder
Widget _buildBottomNavigationBar1() {
List<BottomNavigationBarItem> items = List();
return StreamBuilder(
stream: _rationBloC.inputObservable(),
builder: (context,
AsyncSnapshot<Future<List<CementSandAggregateView>>> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData) {
snapshot.data.then((onValue) => {
onValue.forEach((mix) => {})
});
return BottomNavigationBar(
items: items,
currentIndex: _selectedRatio,
fixedColor: Theme.of(context).buttonColor,
onTap: _onItemTapped);
} else {
return new Center(
child: new CircularProgressIndicator(),
);
}
} else {
return new Container(width: 0.0,height: 0.0,);
}
},
);
}
but data is not coming to screen
i have tried this solution but no chance !
can anyone help me to convert future result in to stream ?
Thanks.
Upvotes: 2
Views: 6073
Reputation: 7100
I think _init()
should be calld in initState()
method of StatefulWidget
, or use this code in initState
or build
method.
WidgetBinding.instance.addPostFrameCallback(() => _init());
This means call of the procedure just after 1st frame rendered, i.e. just after build
.
Upvotes: 0
Reputation: 4741
A simple approach to achive this is await
for the future complete and then put the data inside your stream.
In your bloc class:
void _init() async {
List<CementSandAggregateView> data = await provider.getAllRatios();
_cSAMixController.add(data);
}
CementSandAggregateMixBloC(){
provider = new BLoCProvider();
_cSAMixController = BehaviorSubject< List<CementSandAggregateView> >();
_init();
}
Upvotes: 3