0

I am using the phone_number_field package in a project, which is utilizing flag SVGs from the circle_flags package. Based on the documentation and example of circle_flags, it has a preload function that I can utilize to achieve this. I have verified it via the following code and it works fine (the SVGs preload successfully, and I can view them even when offline):

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

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

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool preloaded = false;
  bool showFlags = false;

  @override
  void initState() {
    super.initState();
    // preloading flags so they how instantly (mostly useful for web)
    if (!preloaded) {
      CircleFlag.preload(Flag.values);
      preloaded = true;
    }
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    
  }

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        brightness: Brightness.light,
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Flags'),
        ),
        body: showFlags
            ? ListView.builder(
                itemCount: Flag.values.length,
                itemBuilder: (context, index) => Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: ListTile(
                    leading: CircleFlag(
                      Flag.values[index],
                      size: 32,
                    ),
                    title: Text(Flag.values[index]),
                    onTap: () {},
                  ),
                ),
              )
            : Center(
                child: ElevatedButton(
                    onPressed: () {
                      setState(() {
                        showFlags = true;
                      });
                    },
                    child: const Text('show')),
              ),
      ),
    );
  }
}

The problem comes when I try to use the preload function in the example here. The SVGs do not preload, even though the version of circle_flags is the same as the version above.

I see a breakpoint I never placed which takes me to a file called web_entrypoint.dart, which is not a part of my project.

I would appreciate if someone can help me in solving this issue. The sample code I am using is as follows. It is being run on Google Chrome:

import 'package:flutter/material.dart';
import 'package:phone_form_field/phone_form_field.dart';
import 'package:circle_flags/circle_flags.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  CircleFlag.preload(Flag.values);
  runApp(const MyApp());
}

// this example makes uses of lots of properties that would not be there
// in a real scenario for the sake of showing the features.
// For a simpler example see the README

class PhoneFieldView extends StatelessWidget {
  static const supportedLocales = [
    Locale('ar'),
    // not supported by material yet
    // Locale('ckb'),
    Locale('de'),
    Locale('el'),
    Locale('en'),
    Locale('es'),
    Locale('fa'),
    Locale('fr'),
    Locale('hi'),
    Locale('hu'),
    Locale('it'),
    // not supported by material yet
    // Locale('ku'),
    Locale('nb'),
    Locale('nl'),
    Locale('pt'),
    Locale('ru'),
    Locale('sv'),
    Locale('tr'),
    Locale('uz'),
    Locale('zh'),
    // ...
  ];

  final PhoneController controller;
  final FocusNode focusNode;
  final CountrySelectorNavigator selectorNavigator;
  final bool withLabel;
  final bool outlineBorder;
  final bool isCountryButtonPersistant;
  final bool mobileOnly;
  final Locale locale;

  const PhoneFieldView({
    Key? key,
    required this.controller,
    required this.focusNode,
    required this.selectorNavigator,
    required this.withLabel,
    required this.outlineBorder,
    required this.isCountryButtonPersistant,
    required this.mobileOnly,
    required this.locale,
  }) : super(key: key);

  PhoneNumberInputValidator? _getValidator(BuildContext context) {
    List<PhoneNumberInputValidator> validators = [];
    if (mobileOnly) {
      validators.add(PhoneValidator.validMobile(context));
    } else {
      validators.add(PhoneValidator.valid(context));
    }
    return validators.isNotEmpty ? PhoneValidator.compose(validators) : null;
  }

  @override
  Widget build(BuildContext context) {
    return AutofillGroup(
      child: Localizations.override(
        context: context,
        locale: locale,
        child: Builder(
          builder: (context) {
            final label = PhoneFieldLocalization.of(context).phoneNumber;
            return PhoneFormField(
              focusNode: focusNode,
              controller: controller,
              isCountryButtonPersistent: isCountryButtonPersistant,
              autofocus: false,
              autofillHints: const [AutofillHints.telephoneNumber],
              countrySelectorNavigator: selectorNavigator,
              decoration: InputDecoration(
                  label: withLabel ? Text(label) : null,
                  border: outlineBorder
                      ? OutlineInputBorder(
                          borderRadius: BorderRadius.circular(50))
                      : const UnderlineInputBorder(),
                  hintText: withLabel ? '' : label,
                  contentPadding: const EdgeInsets.all(0)),
              enabled: true,
              countryButtonStyle: CountryButtonStyle(
                  showFlag: true,
                  showIsoCode: false,
                  showDialCode: true,
                  showDropdownIcon: true,
                  borderRadius: BorderRadius.circular(50)),

              validator: _getValidator(context),
              autovalidateMode: AutovalidateMode.onUserInteraction,
              cursorColor: Theme.of(context).colorScheme.primary,
              // ignore: avoid_print
              onSaved: (p) => print('saved $p'),
              // ignore: avoid_print
              onChanged: (p) => print('changed $p'),
            );
          },
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    CircleFlag.preload(Flag.values);
    return MaterialApp(
      localizationsDelegates: PhoneFieldLocalization.delegates,
      supportedLocales: PhoneFieldView.supportedLocales,
      locale: const Locale('en'),
      title: 'Phone field demo',
      theme: ThemeData(
        brightness: Brightness.dark,
        primarySwatch: Colors.blue,
      ),
      home: const PhoneFormFieldScreen(),
    );
  }
}

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

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

class PhoneFormFieldScreenState extends State<PhoneFormFieldScreen> {
  late PhoneController controller;
  final FocusNode focusNode = FocusNode();

  bool outlineBorder = true;
  bool mobileOnly = true;
  bool isCountryButtonPersistent = true;
  bool withLabel = true;
  CountrySelectorNavigator selectorNavigator =
      const CountrySelectorNavigator.page();
  Locale locale = const Locale('en');
  final formKey = GlobalKey<FormState>();

  @override
  initState() {
    super.initState();
    CircleFlag.preload(Flag.values);
    controller = PhoneController();
    controller.addListener(() => setState(() {}));
  }

  @override
  void dispose() {
    super.dispose();
    controller.dispose();
  }

  @override
  Widget build(BuildContext context) {
    CircleFlag.preload(Flag.values);
    return Scaffold(
      appBar: AppBar(
        title: const Text('Phone_form_field'),
      ),
      body: SingleChildScrollView(
        child: Center(
          child: Container(
            constraints: const BoxConstraints(maxWidth: 600),
            child: Card(
              child: Padding(
                padding: const EdgeInsets.all(20.0),
                child: Column(
                  children: [
                    SwitchListTile(
                      value: outlineBorder,
                      onChanged: (v) => setState(() => outlineBorder = v),
                      title: const Text('Outlined border'),
                    ),
                    SwitchListTile(
                      value: withLabel,
                      onChanged: (v) => setState(() => withLabel = v),
                      title: const Text('Label'),
                    ),
                    SwitchListTile(
                      value: isCountryButtonPersistent,
                      onChanged: (v) =>
                          setState(() => isCountryButtonPersistent = v),
                      title: const Text('Persistent country chip'),
                    ),
                    SwitchListTile(
                      value: mobileOnly,
                      onChanged: (v) => setState(() => mobileOnly = v),
                      title: const Text('Mobile phone number only'),
                    ),
                    ListTile(
                      title: Wrap(
                        alignment: WrapAlignment.spaceBetween,
                        crossAxisAlignment: WrapCrossAlignment.center,
                        children: [
                          const Text('Language: '),
                          DropdownButton<Locale>(
                            value: locale,
                            onChanged: (Locale? value) {
                              if (value != null) {
                                setState(() => locale = value);
                              }
                            },
                            items: [
                              for (final locale
                                  in PhoneFieldView.supportedLocales)
                                DropdownMenuItem(
                                  value: locale,
                                  child: Text(locale.toLanguageTag()),
                                ),
                            ],
                          ),
                        ],
                      ),
                    ),
                    ListTile(
                      title: Wrap(
                        alignment: WrapAlignment.spaceBetween,
                        crossAxisAlignment: WrapCrossAlignment.center,
                        children: [
                          const Text('Country selector: '),
                          DropdownButton<CountrySelectorNavigator>(
                            value: selectorNavigator,
                            onChanged: (CountrySelectorNavigator? value) {
                              if (value != null) {
                                setState(() => selectorNavigator = value);
                              }
                            },
                            items: const [
                              DropdownMenuItem(
                                value: CountrySelectorNavigator.bottomSheet(
                                    favorites: [IsoCode.GU, IsoCode.GY]),
                                child: Text('Bottom sheet'),
                              ),
                              DropdownMenuItem(
                                value: CountrySelectorNavigator
                                    .draggableBottomSheet(),
                                child: Text('Draggable modal sheet'),
                              ),
                              DropdownMenuItem(
                                value:
                                    CountrySelectorNavigator.modalBottomSheet(),
                                child: Text('Modal sheet'),
                              ),
                              DropdownMenuItem(
                                value: CountrySelectorNavigator.dialog(
                                  width: 720,
                                ),
                                child: Text('Dialog'),
                              ),
                              DropdownMenuItem(
                                value: CountrySelectorNavigator.page(),
                                child: Text('Page'),
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                    const SizedBox(height: 40),
                    Form(
                      key: formKey,
                      child: Column(
                        children: [
                          PhoneFieldView(
                            controller: controller,
                            focusNode: focusNode,
                            selectorNavigator: selectorNavigator,
                            withLabel: withLabel,
                            outlineBorder: outlineBorder,
                            isCountryButtonPersistant:
                                isCountryButtonPersistent,
                            mobileOnly: mobileOnly,
                            locale: locale,
                          ),
                        ],
                      ),
                    ),
                    const SizedBox(height: 12),
                    Text(controller.value.toString()),
                    Text('is valid mobile number '
                        '${controller.value.isValid(type: PhoneNumberType.mobile)}'),
                    Text(
                        'is valid fixed line number ${controller.value.isValid(type: PhoneNumberType.fixedLine)}'),
                    const SizedBox(height: 12),
                    ElevatedButton(
                      onPressed: () => formKey.currentState?.reset(),
                      child: const Text('reset'),
                    ),
                    const SizedBox(height: 12),
                    ElevatedButton(
                      onPressed: () {
                        controller.selectNationalNumber();
                        focusNode.requestFocus();
                      },
                      child: const Text('Select national number'),
                    ),
                    const SizedBox(height: 12),
                    ElevatedButton(
                      onPressed: () => controller.value =
                          PhoneNumber.parse('+33 699 999 999'),
                      child: const Text('Set +33 699 999 999'),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

A part of the error log is as follows:

Error while trying to load an asset: Flutter Web engine failed to complete HTTP request to fetch "assets/packages/circle_flags/assets/svg/af.svg": TypeError: Failed to fetch
Error while trying to load an asset: Flutter Web engine failed to complete HTTP request to fetch "assets/packages/circle_flags/assets/svg/ax.svg": TypeError: Failed to fetch
Error while trying to load an asset: Flutter Web engine failed to complete HTTP request to fetch "assets/packages/circle_flags/assets/svg/al.svg": TypeError: Failed to fetch
Error while trying to load an asset: Flutter Web engine failed to complete HTTP request to fetch "assets/packages/circle_flags/assets/svg/dz.svg": TypeError: Failed to fetch
Error while trying to load an asset: Flutter Web engine failed to complete HTTP request to fetch "assets/packages/circle_flags/assets/svg/as.svg": TypeError: Failed to fetch
Error while trying to load an asset: Flutter Web engine failed to complete HTTP request to fetch "assets/packages/circle_flags/assets/svg/ad.svg": TypeError: Failed to fetch
Error while trying to load an asset: Flutter Web engine failed to complete HTTP request to fetch "assets/packages/circle_flags/assets/svg/ao.svg": TypeError: Failed to fetch

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.