-
Notifications
You must be signed in to change notification settings - Fork 220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BloC store Model to Redux without being noticed if I call BloC event in Redux onInit #175
Comments
these code of redux learn from this website
https://hackernoon.com/flutter-redux-how-to-make-shopping-list-app-1cd315e79b65
I have change my code, but I still want to know how to use *redux *the
right way so I didn't close it.
Now the *redux *pass the *globalstate *when call bloc in *BlocProvider*,
but i still call dispatch in *converter*, and it run well until now.
Like this
return StoreConnector<GlobalModel, GlobalModel>(
converter: (store)=>store.state,
builder: (context, globalstate){
return BlocProvider<TabmeBloc>(
create: (context) {
return TabmeBloc(globalstate.accountInfo, globalstate.recorded);
},
child: TabMePage(),
);
},
);
but like what I said, im still call *dispatch *in *converter*
return StoreConnector<GlobalModel, OnUpdateRecordedAttendanceCallback>(
converter: (store) => (recordGlobal) {
store.dispatch(ActionUpdateAttendance(recordGlobal));
},
builder: (context, callback){
.....
}
);
typedef OnUpdateRecordedAttendanceCallback = Function(RecordedAttendance
recordedGlobal);
I call *calback *in *BlocListener* when *blocstate* *onSuccess*, to update
my *globalstate*. Can you give me advice how the right way
…On Thu, 7 May 2020 at 15:22, Jeonghoon Kim ***@***.***> wrote:
????
Hi, Are you calling dispatch in converter?
converter: (store)=>(informasiGlobal)=>(){
store.dispatch(ActionStoringInformation(informasi));
},
You can't do that
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#175 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AD57XIPCOJDAI33CO7TGFA3RQJVU3ANCNFSM4MF2CSDQ>
.
|
Redux was built initialy over Flux architecture concept, to built Javascript apps, start with this: https://www.educative.io/blog/understanding-redux, and go on from there... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I use Redux to handle my globalstate, and BloC as localstate. I need to store my globalmodel in Redux to my BloC model on Redux onInit. I call BloC event in Redux onInit to get my BloC model same as globalmodel. But, I got my Redux model change even if I dont callback Redux update model methode when my BloC doing update model. But if I didn't call BloC event in Redux onInit, the model keep flow well. How I can handle this, so that my globalmodel didn't change when I update my BloC model?
this is my code:
import 'dart:async';
import 'package:kmb/redux/actions.dart';
import 'package:kmb/redux/global-model.dart';
import 'package:kmb/src/models/model-account.dart';
import 'package:kmb/src/views/settings-page/place-page/controller/place-bloc.dart';
import 'package:kmb/src/views/settings-page/place-page/signup-map-dialog.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class PlaceParent extends StatelessWidget {
@OverRide
Widget build(BuildContext context) {
return BlocProvider(
create: (context)=>PlaceBloc(),
child: PlacePage(),
);
}
}
class PlacePage extends StatefulWidget {
@OverRide
_PlacePageState createState() => _PlacePageState();
}
class _PlacePageState extends State {
TextEditingController addressCntrl = new TextEditingController();
Completer _controller = Completer();
final GlobalKey _scaffoldKey = new GlobalKey();
GlobalModel informasi;
PlaceBloc provider;
Set _marker = {};
GoogleMapController mapController;
@OverRide
void initState() {
super.initState();
informasi = GlobalModel.initState();
provider = BlocProvider.of(context);
}
@OverRide
void dispose() {
provider.close();
super.dispose();
}
@OverRide
Widget build(BuildContext context) {
return StoreConnector<GlobalModel,OnStoringInformationUpdatePointCallback>(
key: Key('StoreLocation'),
converter: (store)=>(informasiGlobal)=>(){
store.dispatch(ActionStoringInformation(informasi));
},
onInit: (stored){
print(stored.state.accountInfo.toMap());
informasi = stored.state;
provider.add(PlaceBlocEventStoreInit(informasi.accountInfo));
addressCntrl.text = stored.state.accountInfo.address;
},
onWillChange: (prevstate, nextstate){
print('prevs: $prevstate');
print('prevs: $nextstate');
},
builder: (context, callback){
return BlocListener<PlaceBloc, PlaceBlocModel>(
bloc: BlocProvider.of(context),
listener: (context, state){
if(!state.updateOnProccess){
if(state.updateOnFinish){
print('Masuk Sini CUK');
informasi.accountInfo.updatePoint(state.account);
callback(informasi);
Navigator.of(context).pop();
provider.add(PlaceBlocEventNormalize());
}
}
if(!state.updateLocOnProccess){
if(state.updateLocOnFinish){
addressCntrl.text = state.account.address;
mapController.animateCamera(CameraUpdate.newCameraPosition(CameraPosition(
target: LatLng(state.account.pointLat, state.account.pointLon),
zoom: 16.0
)));
_marker.clear();
_marker.add(Marker(
markerId: MarkerId('001'),
position: LatLng(state.account.pointLat, state.account.pointLon)
));
provider.add(PlaceBlocEventNormalize());
}
}
},
child: BlocBuilder<PlaceBloc, PlaceBlocModel>(
builder: (context, state){
return Scaffold(
key: _scaffoldKey,
body: Container(
decoration: BoxDecoration(
color: Colors.white
),
child: Padding(
padding: const EdgeInsets.only(left:20.0, right:20.0),
child: ListView(
children: [
Divider(
color: Colors.transparent,
height: 30.0,
),
Row(
children: [
InkWell(
child: Icon(Icons.close),
onTap: (){
Navigator.of(context).pop();
},
),
VerticalDivider(
color: Colors.transparent,
width: 10.0,
),
Text('place Point', style: TextStyle(fontSize: 24.0),)
],
),
Divider(
color: Colors.transparent,
height: 20.0,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(5.0),
bottomRight: Radius.circular(5.0),
),
),
child: Column(
children: [
Container(
height: 200.0,
child: GoogleMap(
mapType: MapType.normal,
initialCameraPosition: CameraPosition(
target: LatLng(-6.1753924, 106.8249641),
zoom: 16.0
),
onMapCreated: (controller){
mapController = controller;
// if(state.account.pointLat!=null && state.account.pointLon!=null){
// mapController.animateCamera(CameraUpdate.newCameraPosition(CameraPosition(
// target: LatLng(state.account.pointLat, state.account.pointLon),
// zoom: 16.0
// )));
// _marker.add(Marker(
// markerId: MarkerId('001'),
// position: LatLng(state.account.pointLat, state.account.pointLon)
// ));
// }
_controller.complete(controller);
},
markers: _marker,
),
),
Container(
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(5.0),
bottomRight: Radius.circular(5.0),
),
),
child: Padding(
padding: const EdgeInsets.fromLTRB(16.0,10.0,16.0,10.0),
child: Container(
child: InkWell(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.launch, color: Colors.white, size: 32.0,),
VerticalDivider(
color: Colors.transparent,
width: 10.0,
),
Text('Open Map', style: TextStyle(color: Colors.white, fontSize: 16.0, fontWeight: FontWeight.w600),)
],
),
onTap: (){
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context){
print(state.account.pointLon);
return state.account.pointLon!=null? SignUpMapDialog(
currPositionLat: state.account.pointLat,
currPositionLon: state.account.pointLon,
onItemChoosed: (locparam){
provider.add(PlaceBlocEventStoreUpdateOnProcess());
provider.add(PlaceBlocEventStoreUpdate(Account(pointLat: locparam.pointLoc.latitude, pointLon: locparam.pointLoc.longitude, address: locparam.address)));
},
):SignUpMapDialog(
currPositionLat: -6.1753924,
currPositionLon: 106.8249641,
onItemChoosed: (locparam){
provider.add(PlaceBlocEventStoreUpdateOnProcess());
provider.add(PlaceBlocEventStoreUpdate(Account(pointLat: locparam.pointLoc.latitude, pointLon: locparam.pointLoc.longitude, address: locparam.address)));
},
);
}
);
},
),
),
),
)
],
),
),
Divider(
color: Colors.transparent,
height: 30.0,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Latitude', style: TextStyle(fontWeight: FontWeight.w600,fontSize: 16.0),),
Divider(height: 4.0, color: Colors.transparent,),
Text('${state.account.pointLat}', style: TextStyle(fontSize: 14.0, color: Colors.grey),),
],
),
Padding(
padding: const EdgeInsets.only(top:10.0, bottom:10.0),
child: Divider(height: 1.0, color: Colors.grey,),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Longitude', style: TextStyle(fontWeight: FontWeight.w600,fontSize: 16.0),),
Divider(height: 4.0, color: Colors.transparent,),
Text('${state.account.pointLon}', style: TextStyle(fontSize: 14.0, color: Colors.grey),),
],
),
Padding(
padding: const EdgeInsets.only(top:10.0, bottom:10.0),
child: Divider(height: 1.0, color: Colors.grey,),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Address', style: TextStyle(fontWeight: FontWeight.w600,fontSize: 16.0),),
Container(
child: TextFormField(
decoration: InputDecoration(
hintText: "Address",
),
controller: addressCntrl,
),
),
],
),
Divider(
color: Colors.transparent,
height: 30.0,
),
InkWell(
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.all(Radius.circular(5.0))
),
child: Padding(
padding: const EdgeInsets.fromLTRB(10.0,14.0,10.0,14.0),
child: Center(child: Text('Confirm', style: TextStyle(fontSize: 18.0, color: Colors.white, fontWeight: FontWeight.w700),)),
)
),
onTap: (){
provider.add(PlaceBlocEventUpdateRemoteOnProcess());
provider.add(PlaceBlocEventUpdateRemote(state.account));
},
),
Divider(
color: Colors.transparent,
height: 30.0,
),
],
),
),
),
);
}
)
);
}
);
}
}
typedef OnStoringInformationUpdatePointCallback = Function(GlobalModel informasiGlobal);
my Bloc code:
import 'dart:convert';
import 'package:bloc/bloc.dart';
import 'package:kmb/src/models/model-account.dart';
import 'package:kmb/src/services/api-serv.dart';
import 'package:equatable/equatable.dart';
import 'package:kmb/src/globals.dart' as globals;
import 'package:http/http.dart';
class PlaceBlocModel{
Account account;
bool onInit;
bool updateOnProccess;
bool updateOnFinish;
bool updateLocOnProccess;
bool updateLocOnFinish;
PlaceBlocModel({
this.account,
this.onInit,
this.updateOnProccess,
this.updateOnFinish,
this.updateLocOnFinish,
this.updateLocOnProccess
});
PlaceBlocModel.initState(){
this.account = Account.initState();
this.onInit = true;
this.updateOnProccess = false;
this.updateOnFinish = false;
this.updateLocOnProccess = false;
this.updateLocOnFinish = false;
}
void fromMapUpdate(Map<String, dynamic> map){
this.account.pointLat = map['data']['point_lat'];
this.account.pointLon = map['data']['point_lon'];
this.account.address = map['data']['address'];
this.account.token = map['token'];
}
void locUpdate(Account accountMap){
this.account.pointLat = accountMap.pointLat;
this.account.pointLon = accountMap.pointLon;
this.account.address = accountMap.address;
}
PlaceBlocModel.copy(PlaceBlocModel state){
this.account = state.account;
this.onInit = state.onInit;
this.updateOnProccess = state.updateOnProccess;
this.updateOnFinish = state.updateOnFinish;
this.updateLocOnProccess = state.updateLocOnProccess;
this.updateLocOnFinish = state.updateLocOnFinish;
}
}
abstract class PlaceBlocEvent extends Equatable{
@OverRide
List get props => [];
}
class PlaceBlocEventStoreInit extends PlaceBlocEvent{
final Account account;
PlaceBlocEventStoreInit(this.account);
}
class PlaceBlocEventStoreUpdate extends PlaceBlocEvent{
final Account account;
PlaceBlocEventStoreUpdate(this.account);
}
class PlaceBlocEventStoreUpdateOnProcess extends PlaceBlocEvent{}
class PlaceBlocEventUpdateRemoteOnProcess extends PlaceBlocEvent{}
class PlaceBlocEventUpdateRemote extends PlaceBlocEvent{
final Account account;
PlaceBlocEventUpdateRemote(this.account);
}
class PlaceBlocEventNormalize extends PlaceBlocEvent{}
class PlaceBloc extends Bloc<PlaceBlocEvent, PlaceBlocModel>{
@OverRide
PlaceBlocModel get initialState => PlaceBlocModel.initState();
@OverRide
Stream mapEventToState(PlaceBlocEvent event)async* {
if(event is PlaceBlocEventUpdateRemote){
print(event.account.toMapPlacePoint());
PlaceBlocModel retval = await PlacePointUpdate(event.account.toMapPlacePoint(), state);
yield retval;
}else if(event is PlaceBlocEventStoreInit){
if(state.onInit){
yield PlaceBlocModel(account: event.account, onInit: false, updateOnFinish: false, updateOnProccess: false, updateLocOnFinish: false, updateLocOnProccess: false);
}
}else if(event is PlaceBlocEventUpdateRemoteOnProcess){
yield PlaceBlocModel(account: state.account, onInit: false, updateOnFinish: false, updateOnProccess: true, updateLocOnFinish: state.updateLocOnFinish, updateLocOnProccess: state.updateLocOnProccess);
}else if(event is PlaceBlocEventStoreUpdateOnProcess){
yield PlaceBlocModel(account: state.account, onInit: false, updateOnFinish: state.updateOnFinish, updateOnProccess: state.updateOnProccess, updateLocOnFinish: false, updateLocOnProccess: true);
}else if(event is PlaceBlocEventStoreUpdate){
PlaceBlocModel currState = PlaceBlocModel.copy(state);
currState.locUpdate(event.account);
currState.updateLocOnFinish = true;
currState.updateLocOnProccess = false;
yield currState;
}else if(event is PlaceBlocEventNormalize){
yield PlaceBlocModel(account: state.account, onInit: false, updateOnFinish: false, updateOnProccess: false, updateLocOnFinish: false, updateLocOnProccess: false);
}
}
Future PlacePointUpdate(Map<String, dynamic> map, PlaceBlocModel state)async{
final Response response = await callApi(APIMethode.POST, globals.urlUpdatePlacePoint(), data: map);
if(response.statusCode == 200){
final jsonRes = json.decode(response.body);
if(jsonRes['error']==true){
return PlaceBlocModel(account: state.account, updateOnFinish: true, updateOnProccess: false);
}else{
print(map);
PlaceBlocModel Place = PlaceBlocModel.copy(state)..fromMapUpdate(jsonRes);
Place.updateOnFinish = true;
Place.updateOnProccess = false;
return Place;
}
}else{
return PlaceBlocModel(account: state.account, updateOnFinish: true, updateOnProccess: false);
}
}
}
The text was updated successfully, but these errors were encountered: