Flutter MobX Observer does not fire upon @action
Okay, seems that this part
@observable
List<File> images = [];
does not work (currently?)
Replacing it with
final images = ObservableList<File>.of([]);
will yield the wanted results
Rhywden
Updated on December 17, 2022Comments
-
Rhywden over 1 year
I'm using a MultiProvider which wraps my whole app. I'm already using another Store/Observer for authentication/login and that part works as it should. I just added another store which reflects the photos a user has taken and which then get displayed at two different places before uploading.
The "taking the photo" and "insert them into the store" works fine. The part which is then supposed to reactively display the photos... not so much.
Relevant code:
import 'dart:io'; import 'package:mobx/mobx.dart'; import 'package:image_picker/image_picker.dart'; part 'photoview_store.g.dart'; class PhotoviewStore = _PhotoviewStore with _$PhotoviewStore; abstract class _PhotoviewStore with Store { @observable List<File> images = []; @computed int get length => images.length; @action Future getImage({bool fromGallery: true}) async { ImageSource source = fromGallery ? ImageSource.gallery : ImageSource.camera; File _image; try { _image = await ImagePicker.pickImage(source: source); if(images.length >= 3) images.removeLast(); images.insert(0, _image); print('New length: ${images.length}'); } catch(_) { print('Error getting image'); } } @action void removePicture(int index) { images.removeAt(index); } }
The
@computed
I added because I thought it might be problematic to accessimages.length
in the Observer. Doesn't do anything, though.class NeuesAnliegen extends StatefulWidget { @override _NeuesAnliegenState createState() => _NeuesAnliegenState(); } class _NeuesAnliegenState extends State<NeuesAnliegen> with AutomaticKeepAliveClientMixin{ [...] @override Widget build(BuildContext context) { final photoStore = Provider.of<PhotoviewStore>(context); super.build(context); [...] Row( children: <Widget>[ Expanded( flex: 1, child: Observer(builder: (_) { print(photoStore.length); if(photoStore.length < 1) return Container(); return GestureDetector( child: Image.file(photoStore.images[0], height: 100), onTap: () { }, ); },) ), Expanded( flex: 1, child: Observer(builder: (_) { if(photoStore.length < 2) return Container(); return GestureDetector( child: Image.file(photoStore.images[1], height: 100), onTap: () { }, ); },) ), Expanded( flex: 1, child: Observer(builder: (_) { if(photoStore.length < 3) return Container(); return GestureDetector( child: Image.file(photoStore.images[2], height: 100), onTap: () { }, ); },) ) ], ), [...] Expanded( child: RaisedButton.icon( onPressed: () => photoStore.getImage(fromGallery: false,), icon: Icon(Icons.camera), label: Text('Foto aufnehmen') ), ),
So, I can take a photo just fine and it does get added to the
images
list but theObservable
never fires.