Home > OS >  FutureBuilder snapshot data type is not correct
FutureBuilder snapshot data type is not correct

Time:06-11

I am using a Flutter FutureBuilder widget and SharedPreferences, to wait for the preferences to be loaded before using them to get the language and pass them to child widgets.

Here is my code:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:i18n_extension/i18n_widget.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'helpers/color.dart';
import 'pages/home.dart';
import '../constants.dart';

void main() {
  runApp(
    const ProviderScope(
      child: MyApp(),
    ),
  );
}

Future<SharedPreferences> getPrefs() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  return prefs;
}

Locale getLanguageSetting(SharedPreferences prefs) {
  String? lang = prefs.getString('language');
  if (LANGUAGES.contains(lang)) {
    return Locale(lang, '');
  }
  return const Locale('en', '')
}

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

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: getPrefs(),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
              return MaterialApp(
      localizationsDelegates: const [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const [
        Locale('en', ''),
        Locale('jp', ''),
      ],
      home: I18n(
          initialLocale: getLanguageSetting(snapshot.data),
          child: HomeWidget(getPrefs: snapshot.data)), // to force locale to jp
    );
        } else {
          return const Center(
            child: CircularProgressIndicator(),
          );
        }
      }
    );
  }
}

But I have trouble with the type of snapshot.data: both the method and widget I'm passing it to send back a type error The argument type 'Object?' can't be assigned to the parameter type 'SharedPreferences'.

I thought snapshot.data should be of type SharedPreferences according to future: getPrefs(), but it seems it's of type AsyncSnapshot<Object?>.

Why? Should I cast snapshot.data into a SharedPreferences type (I'm not very comfortable with casting)? How can I do that?

CodePudding user response:

Define the type in snapshot as AsyncSnapshot<SharedPreferences> snapshot. Then If you are running a null safe version change the type of sharedPreferences to SharedPreferences? in getLanguageSetting also.

    import 'package:flutter/material.dart';
    import 'package:shared_preferences/shared_preferences.dart';

    void main() {
      runApp(MyApp());
    }

    Future<SharedPreferences> getPrefs() async {
      SharedPreferences prefs = await SharedPreferences.getInstance();
      return prefs;
    }

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

      @override
      Widget build(BuildContext context) {
        return FutureBuilder(
            future: getPrefs(),
            builder: (context, AsyncSnapshot<SharedPreferences?> snapshot) {
              if (snapshot.hasData) {
                print(snapshot.data.runtimeType);
                getLanguageSetting(snapshot.data);
                return MaterialApp(
                    localizationsDelegates: const [],
                    supportedLocales: const [
                      Locale('en', ''),
                      Locale('jp', ''),
                    ],
                    home: Container(
                      color: Colors.red,
                    ));
              } else {
                return const Center(
                  child: CircularProgressIndicator(),
                );
              }
            });
      }
    }

    void getLanguageSetting(SharedPreferences? prefs) {
      print(prefs.runtimeType);
    }


  • Related