0

I'm building an application to stream anime from a popular anime site. However, I would like to run a certain Provider method at app start. Once the app is loaded, I would like to fetch some anime from an api, before a user clicks on "Search" tab.

I would like to point out that this solution didn't work for me: How to call method at App start if I am using provider?

Here's how my app looks like: Image1

Image2

My code:

main.dart

import 'package:anime_go/pages/home.dart';
import 'package:anime_go/providers/anime.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    EasyLocalization(
      supportedLocales: [Locale('en', 'US')],
      path: 'lib/assets/translations',
      fallbackLocale: Locale('en', 'US'),
      child: AnimeGO(),
    ),
  );
}

class AnimeGO extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => Anime()..addAnimeList(),
      child: MaterialApp(
        theme: ThemeData(
          primaryColor: Colors.blueGrey[800],
        ),
        title: 'title'.tr(),
        localizationsDelegates: context.localizationDelegates,
        supportedLocales: context.supportedLocales,
        locale: context.locale,
        home: HomeScreen(),
      ),
    );
  }
}

providers/anime.dart

import 'package:anime_go/services/anime_twist.dart';
import 'package:flutter/cupertino.dart';

class Anime extends ChangeNotifier {
  var allAnimeList;
  final AnimeTwistApiService api = AnimeTwistApiService();

  void addAnimeList() async {
    allAnimeList = await api.getAllAnime();
    notifyListeners();
  }
}

pages/tabs/search.dart

import 'package:anime_go/providers/anime.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class SearchTab extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final allAnimeList = context.watch<Anime>().allAnimeList;
    return Center(
      child: Column(
        children: <Widget>[
          for (var i = 0; i < allAnimeList.length; i++)
            Text(allAnimeList[i].title.toString())
        ],
      ),
    );
  }
}

pages/home.dart

import 'package:anime_go/pages/tabs/home.dart';
import 'package:anime_go/pages/tabs/search.dart';
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  int _selectedIndex = 0;

  final List<Widget> _children = <Widget>[
    HomeTab(),
    SearchTab(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blueGrey[700],
      appBar: AppBar(
        title: Text('title').tr(),
      ),
      body: _children[_selectedIndex],
      bottomNavigationBar: BottomNavigationBar(
          backgroundColor: Colors.blueGrey[800],
          items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              title: Text('home').tr(),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.search),
              title: Text('search').tr(),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.settings),
              title: Text('settings').tr(),
            )
          ],
          currentIndex: _selectedIndex,
          selectedItemColor: Colors.white,
          unselectedItemColor: Colors.grey,
          onTap: _onItemTapped),
    );
  }

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }
}
szakes1
  • 794
  • 3
  • 16
  • 35

2 Answers2

0

In your ChangeNotifier class, add an init() method that will run when the provider is instantiated:

 class Anime extends ChangeNotifier {
    Anime() {
        init();
    }
    var allAnimeList;
    final AnimeTwistApiService api = AnimeTwistApiService();

    void init() async {
        allAnimeList = await api.getAllAnime();
        notifyListeners();
    }
}

Then, in your main build method set the provider's lazy property to false:

    return ChangeNotifierProvider(
          create: (_) => Anime(), 
          lazy: false,
          child: MaterialApp(

This way, your provider's init method will run when first encountered, when the app starts up, and not when first needed.

whidev
  • 161
  • 1
  • 3
-1

Call Provider inside HomeScreen

var allAnimeList

  final List<Widget> _children = <Widget>[
    HomeTab(),
    SearchTab(allAnimeList),
  ];

 @override
  Widget build(BuildContext context) {
   allAnimeList = context.watch<Anime>().allAnimeList;
    return Scaffold(
      backgroundColor: Colors.blueGrey[700],
      appBar: AppBar(
        title: Text('title').tr(),
      ),
      // Rest code
Jitesh Mohite
  • 31,138
  • 12
  • 157
  • 147