Mobx.dart: Observer not works

Created on 23 May 2019  路  4Comments  路  Source: mobxjs/mobx.dart

I create an Entry for check user's login state, here is my code
This is my user.dart

import 'package:mobx/mobx.dart';

// Include generated file
part 'user.g.dart';

// This is the class used by rest of your codebase
class User = _User with _$User;


// The store-class
abstract class _User implements Store {

  @observable
  bool loggedIn = false;

  @action
  void login() {
      loggedIn = true;
  }

}

my main.dart

...
import 'store/user.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Entry(),
      routes:  <String, WidgetBuilder> {
      },
    );
  }
}

class Entry extends StatefulWidget {
  const Entry({Key key}) : super(key: key);

  @override
  _EntryState createState() => _EntryState();
}

class _EntryState extends State<Entry> {
  final _user = User();

//=================here!=======================
  @override
  Widget build(BuildContext context)  => Observer(
    builder: (_) => _user.loggedIn ? MyHomePage() : Login(),
  );
}
//=============================================

in my login.dart

import 'package:flutter/material.dart';
import '../store/user.dart';

final user = User();

class Login extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("login")
      ),
      body: Center(
        child: RaisedButton(onPressed: user.login),
      )
    );
  }
}

when I try to login, I want my App leave the login page and turn into the AppHome class, but nothing happen

so, whats the problem about my code? please help me

Most helpful comment

Wrap your Entry() in a Provider along with the User store. The child widgets can access your User store through Provider.of().

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Provider<User>(
        builder: (_) => User(),
        child: Entry(),
      ),
      routes:  <String, WidgetBuilder> {
      },
    );
  }
class Login extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
     final user = Provider.of<User>(context); // access User store from the parent widget
     return Scaffold(
      appBar: AppBar(
        title: Text("login")
      ),
      body: Center(
        child: RaisedButton(onPressed: user.login),
      )
    );
  }
}
class _EntryState extends State<Entry> {
  @override
  Widget build(BuildContext context)  { 
    final user = Provider.of<User>(context); // access User store from the parent widget

    return Observer(
     builder: (_) => user.loggedIn ? MyHomePage() : Login(),
     );
   }
}

All 4 comments

You have 2 reference of your User store.

class _EntryState extends State<Entry> {
  final _user = User(); // first

  @override
  Widget build(BuildContext context)  => Observer(
    builder: (_) => _user.loggedIn ? MyHomePage() : Login(),
  );
}
final user = User(); // second 

class Login extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("login")
      ),
      body: Center(
        child: RaisedButton(onPressed: user.login),
      )
    );
  }
}

You must have only one reference. Use provider package suggested in the mobx sites https://mobx.pub/guides/stores

sorry, I still not understand how can merge my user reference, can you give some example ? thanks

Wrap your Entry() in a Provider along with the User store. The child widgets can access your User store through Provider.of().

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Provider<User>(
        builder: (_) => User(),
        child: Entry(),
      ),
      routes:  <String, WidgetBuilder> {
      },
    );
  }
class Login extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
     final user = Provider.of<User>(context); // access User store from the parent widget
     return Scaffold(
      appBar: AppBar(
        title: Text("login")
      ),
      body: Center(
        child: RaisedButton(onPressed: user.login),
      )
    );
  }
}
class _EntryState extends State<Entry> {
  @override
  Widget build(BuildContext context)  { 
    final user = Provider.of<User>(context); // access User store from the parent widget

    return Observer(
     builder: (_) => user.loggedIn ? MyHomePage() : Login(),
     );
   }
}

it works , Thank you!

Was this page helpful?
0 / 5 - 0 ratings