What is future provider value flutter

Like any other Provider, FutureProvider also provides a value. But with the modified version of Provider package, the usage has changed a little bit.

We’ll jump into that code in a minute and show how it works.

However, before that let us try to understand the main principle of FutureProvider.

As the name suggests, FutureProvider provides a Future value that might not be ready when the widget that gets the value is already ready to use. And that has a lot to do with Future class in Flutter.

That’s a big difference with other providers. Since, the provided value might take time to appear, it must not be null. That’s why, the FutureProvider has a required parameter “initialdata”, which is the initial value that a widget can use until it gets the proper provided value.

Once the data is ready, FutureProvider communicates with the descendant widget to rebuild and use the new value.

However, there is a caveat.

FutureProvider by default provides the initial data, and after that it provides the future value. But for once. Widget that rely on FutureProvider will rebuild once.

However, FutureProvider can be configured to change again if in future a new value is about to come.

We’ll look into that topic in another section. Another important thing to note here is FutureProvider is used to provide data to the the widget tree that is asynchronous. That is why we’re saying that Future will schedule a task first, and after that releases the current thread back to work until the FutureProvider is not resolved.

While other providers provide a ready-made value of some type, the FutureProvider tells the widget to wait and promises that it will provide a value of some type.

If you’re a beginner, don’t worry, we’ll discuss these topics in great detail later.

In our last section on the usage of Provider package, we’ve seen what we can do with Provider. To tell you frankly, we can do many things in Flutter with one single package Provider.

In this section, we’ll try to build a flutter application, a blog, with the help of FutureProvider package. And at the same time we’ll show how FutureProvider can pass any value of any type.

Just for little recapitulation let us first remember what Provider is. Provider package in Flutter serves us in many purposes, that also includes passing a global style or data across the flutter app. We can pass the provided value through child constructors.

While we build our simple blog application in Flutter, we’ll pass both. A global theme and blog posts through widget class constructors.

Let’s see the full code in one place, although that’s not a good practice. We usually follow a model-view-controller approach to keep our code modular and loosely coupled.

However, if you take a single glance, you will understand how the the provided value descends through the widget tree.

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'model/global_theme.dart';
import '/model/blog_post.dart';
import 'view/home.dart';

void main() {
  runApp(
    /// Providers are above [Root App] instead of inside it, so that tests
    /// can use [Root App] while mocking the providers
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => GlobalTheme()),
        FutureProvider<int>(
          create: (context) => Future.value(1),
          initialData: 2,
        ),
        FutureProvider<String>(
          create: (context) => Future.value('Blog Home Page'),
          initialData: '',
        ),
        FutureProvider<List<BlogPost>>(
          create: (context) => Future.value(blogPosts),
          initialData: const [],
          child: const Home(),
        ),
      ],
      child: const Home(),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    final ThemeData globalTheme = Provider.of<GlobalTheme>(context).globalTheme;
    return MaterialApp(
      title: 'FutureProvider Demo',
      theme: globalTheme,
      home: const HomePage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'Blog Home Page',
          style: Theme.of(context).appBarTheme.titleTextStyle,
        ),
      ),
      body: const HomeBody(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    final blogs = Provider.of<List<BlogPost>>(context);
    final counter = Provider.of<int>(context);
    final blogHead = Provider.of<String>(context);
    return Center(
      child: Column(
        children: [
          Container(
            margin: const EdgeInsets.all(5),
            padding: const EdgeInsets.all(5),
            child: Text(
              'This comes from Future Provider: $counter',
              style: Theme.of(context).textTheme.headline2,
            ),
          ),
          Container(
            margin: const EdgeInsets.all(5),
            padding: const EdgeInsets.all(5),
            child: Text(
              '$blogHead comes from FutureProvider',
              style: Theme.of(context).textTheme.headline1,
            ),
          ),
          Container(
            margin: const EdgeInsets.all(5),
            padding: const EdgeInsets.all(5),
            child: Text(
              'I am a clumsy coder trying to write decent code, and '
              'fiction.'
              ' But there is a friction. '
              'So, I avoid proper diction.',
              style: Theme.of(context).textTheme.bodyText1,
            ),
          ),
          Flexible(
            child: GridView.builder(
              padding: const EdgeInsets.all(10.0),
              itemCount: blogs.length,
              itemBuilder: (ctx, i) => ChangeNotifierProvider.value(
                value: blogs[i],
                child: InkWell(
                  onTap: () {
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => BlogDetail(
                          post: blogs[i],
                        ),
                      ),
                    );
                  },
                  child: Text(blogs[i].title),
                ),
              ),
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 1,
                childAspectRatio: 22 / 2,
                crossAxisSpacing: 2,
                mainAxisSpacing: 2,
              ),
            ),
          )
        ],
      ),
    );
  }
}

class BlogDetail extends StatelessWidget {
  final BlogPost post;
  const BlogDetail({
    Key? key,
    required this.post,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'Blog Page',
          style: Theme.of(context).appBarTheme.titleTextStyle,
        ),
      ),
      body: Center(
        child: ListView(
          children: [
            Container(
              margin: const EdgeInsets.all(5),
              padding: const EdgeInsets.all(5),
              child: Text(
                post.title,
                textAlign: TextAlign.left,
                style: Theme.of(context).textTheme.headline1,
              ),
            ),
            Container(
              margin: const EdgeInsets.all(5),
              padding: const EdgeInsets.all(5),
              child: Text(
                post.content,
                textAlign: TextAlign.left,
                style: Theme.of(context).textTheme.bodyText1,
              ),
            ),
            Container(
              margin: const EdgeInsets.all(5),
              padding: const EdgeInsets.all(5),
              child: Text(
                DateFormat('d MMMM y').format(post.date),
                style: Theme.of(context).textTheme.bodyText2,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

The bold section will only show you how we can use FutureProvider. If we run the app, we’ll see the home screen.

Future provider value example
Future provider value example

The above screenshot shows us how three values of different types are provided by the Future.vaue().

Now we can click any post and to read that in detail.

Flutter blog application with provider shows single post
Flutter blog application with provider shows single post

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

GitHub repository

Technical blog

Twitter

Comments

3 responses to “What is future provider value flutter”

  1. […] Change Notifier Provider works with Future builder here, in the my home page […]

  2. […] Cependant, Dart et Flutter ont sa réponse. Ensemble, ils effectuent des opérations de longue durée à l’aide de Future API, async, attendent des mots-clés, puis des fonctions. […]

  3. […] Cependant, Dart et Flutter ont sa réponse. Ensemble, ils effectuent des opérations de longue durée à l’aide de Future API, async, attendent des mots-clés, puis des fonctions. […]

Leave a Reply