flutter : AutoDisposeFutureProviderFamilyでログインは書けないのかな?

viewにボタンを二つ置いて、、

AutoDisposeFutureProviderFamilyでログイン処理って書けないのかなぁ、、 もう疲れた、、

AutoDisposeFutureProviderFamilyってログイン情報とかフィルタ条件を渡せば、使い勝手が良いように思うんだよね、、

いったい何がどうちがうんだ?

AutoDisposeFutureProviderを使う場合は
AuthRequestStateProviderにして参照可能にする→AuthRequestState
LOGIN2ボタンでAuthRequestStateを更新する。
AutoDisposeFutureProviderAuthRequestStateをwatchするようにしておく
すると、AutoDisposeFutureProviderは再構築される
AutoDisposeFutureProviderが再構築されると
viewも再構築されるてのは、なんとなく理解できる

でも、 AutoDisposeFutureProviderFamilyを入れようとすると良く解らんナァ、、

import 'package:care_smile/data/auth_model.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:care_smile/request_api.dart';

final errorMessageProvider = StateProvider((ref) => '');

// ★StateNotifierとStateNotifierProviderでやる場合はこうかな?

class LoginNotifier extends StateNotifier<LoginState> {
  LoginNotifier(this.ref) : super(const LoginState());
  final Ref ref;  //★ ここが気に入らない
  //データ読み込み処理
  Future<LoginState> readData(name, password) async {
    LoginState loginState = await Repository().login(name, password)
        .onError((error, stackTrace) async {
        ref.watch(errorMessageProvider.notifier).state = "ログインに失敗しました";
      throw Exception(error.toString());
    });

    state = state.copyWith(
      isSaseki: loginState.isSaseki,
      syokuinCode: loginState.syokuinCode,
      accessToken: loginState.accessToken,
      refreshToken: loginState.refreshToken,
    );
    return loginState;
  }
}

final loginProvider = StateNotifierProvider((ref) => LoginNotifier(ref));

// ★StateProviderとAutoDisposeFutureProviderFamilyでやる場合はこうかな?

final loginStateProvider = StateProvider((ref) => const LoginState());

AutoDisposeFutureProviderFamily<LoginState, AuthRequest>
loginRequestFutureProvider = FutureProvider.autoDispose
    .family<LoginState, AuthRequest>(
        (ref, authRequest) async {
          LoginState loginState = await Repository().login(authRequest.name, authRequest.password)
              .onError((error, stackTrace) async {
            ref.watch(errorMessageProvider.notifier).state = "ログインに失敗しました";
            throw Exception(error.toString());
          });

          ref.watch(loginStateProvider.notifier).state
         .copyWith(
            isSaseki: loginState.isSaseki,
            syokuinCode: loginState.syokuinCode,
            accessToken: loginState.accessToken,
            refreshToken: loginState.refreshToken,
          );
          return loginState;
    }
);

呼び出し側も書いてみる、、

import 'package:care_smile/data/auth_model.dart';
import 'package:care_smile/ui/schedule_list.dart';
import 'package:care_smile/request_api.dart';
import 'package:care_smile/provider/login_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

import '../provider/login_view_model.dart';

class LoginApp extends StatelessWidget {
  const LoginApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'アプリ',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: LoginPage(title: 'Login Page'),
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: const [
        Locale("en"),
        Locale("ja"),
      ],
    );
  }
}

class LoginPage extends HookConsumerWidget {
  LoginPage({Key? key, required this.title}) : super(key: key);

  final String title;

  final _userNameTextCtl = TextEditingController();
  final _pwdTextCtl = TextEditingController();
  final FocusNode _userNameFocusNode = FocusNode();
  final FocusNode _passwordNameFocusNode = FocusNode();

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final errorMessage = ref.watch(errorMessageProvider);
    final viewModel = ref.watch(loginProvider.notifier);

    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(errorMessage, style: const TextStyle(color: Colors.red)),
            TextField(
              controller: _userNameTextCtl,
              decoration: const InputDecoration(
                filled: true,
                labelText: 'Username',
              ),
              focusNode: _userNameFocusNode,
            ),
            const SizedBox(height: 10.0),
            TextField(
              controller: _pwdTextCtl,
              decoration: const InputDecoration(
                filled: true,
                labelText: 'Password',
              ),
              focusNode: _passwordNameFocusNode,
              obscureText: true,
            ),
            ButtonBar(
              children: <Widget>[
                ElevatedButton(  //★ ボタン1
                    child: const Text('LOGIN'),
                    onPressed: () {
                      viewModel.readData(
                          _userNameTextCtl.text, _pwdTextCtl.text).then(
                              (loginStatus) {
                                debugPrint('LOGIN:' + loginStatus.accessToken);
                        Navigator.push(context,
                            MaterialPageRoute(builder: (context) =>
                                ScheduleList(loginStatus: loginStatus)));
                            }
                        ).onError((error, stackTrace) {
                        // _userNameTextController.clear();
                        _pwdTextCtl.clear();
                      });
                    }),
                ElevatedButton( //★ ボタン2
                    child: const Text('LOGIN2'),
                    onPressed: () {
                      AuthRequest req = AuthRequest(name: _userNameTextCtl.text,
                          password: _pwdTextCtl.text);
                      final messageProvider = ref.watch(loginRequestFutureProvider(req)); //watchは変だな、、
                      messageProvider.when(
                        data: (loginState) {
                            debugPrint('LOGIN2:' + loginState.accessToken);
                        },
                        error: (error, stackTrace) {
                          Future(() {
                            showDialog(
                                context: context,
                                builder: (_) {
                                  return AlertDialog(
                                    title: const Text(
                                        "認証に失敗しました。再ログインをお願いします。"),
                                    actions: [
                                      TextButton(
                                          onPressed: () =>
                                              Navigator.pop(context),
                                          child: const Text("OK")),
                                    ],
                                  );
                                }).then((_) {
                              Navigator.pop(context);
                            });
                          });
                        },
                        loading: () =>
                        const AspectRatio(aspectRatio: 0.01,
                          child: CircularProgressIndicator(),
                        ),
                      );
                    }),

              ],
            ),
          ],
        ),
      ),
    );
  }
}

/* -----codeの行番号----- */