Multi provider flutter in Web App

While building our web app, we face a challenge. Firstly, we need to merge multiple providers. To solve this issue we have used a multi provider. 

As a result, it improves the readability of our code. Secondly, it reduces boilerplate code. Why? Because otherwise we have to nest multiple layers of providers which doesn’t sound practical.

Consider the following code.

Provider<FirstUser>(
  create: (_) => FirstUser(),
  child: Provider<SecondUser>(
    create: (_) => SecondUser(),
    child: Provider<ThirdUser>(
      create: (_) => ThirdUser(),
      child: MaterialApp(),
    ),
  ),
),

We cannot go on doing this forever. It’d be better to write this way:

MultiProvider(
  providers: [
    Provider<FirstUser>(create: (_) => FirstUser()),
    Provider<SecondUser>(create: (_) => SecondUser()),
    Provider<ThirdUser>(create: (_) => ThirdUser()),
  ],
  child: MaterialApp(),
)

We see that the MultiProvider class has a property called “providers” which expects a list of Providers. 

As an outcome, it becomes much easier for us to provide any type to a child widget. 

Suppose we want to provide three different types of data to a child widget. 

Data Provider Flutter
Data Provider Flutter

Firstly, we will provide a user defined type or object User.

Secondly, we provide a String data type, and finally we provide an integer data type.

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

import '../model/custom_theme.dart';
import 'second_app.dart';

class ClassTitle {
  late String title;
  ClassTitle(this.title);
}

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

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        Provider<ClassTitle>(
          create: (context) => ClassTitle('John\'s Blog'),
        ),
        Provider<String>(
          create: (context) => 'John',
        ),
        Provider<int>(
          create: (context) => 23,
        ),
      ],
      child: MaterialApp(
        title: 'Angel\'s Blog',
        theme: CustomTheme.theme,
        home: const SecondApp(),
      ),
    );
  }
}

We’re going to provide these different data types to the child widget SecondApp().

For example, now we can grab those data types quite easily in the child widget.

Let’s see the code.

import 'package:flutter/material.dart';

import 'package:provider/provider.dart';

import 'first_app.dart';

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

  @override
  Widget build(BuildContext context) {
    final title = Provider.of<ClassTitle>(context);
    final name = Provider.of<String>(context);
    final age = Provider.of<int>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text(
          title.title,
          style: const TextStyle(
            color: Colors.black,
            fontSize: 30.0,
            fontWeight: FontWeight.bold,
          ),
        ),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          mainAxisSize: MainAxisSize.max,
          children: [
            Text.rich(
              TextSpan(
                text: 'Your name is ',
                style: const TextStyle(
                  color: Colors.black,
                  fontSize: 30.0,
                  fontWeight: FontWeight.bold,
                ),
                children: <InlineSpan>[
                  WidgetSpan(
                    alignment: PlaceholderAlignment.baseline,
                    baseline: TextBaseline.alphabetic,
                    child: ConstrainedBox(
                      constraints: const BoxConstraints(maxWidth: 100),
                      child: Text(
                        name,
                        style: Theme.of(context).textTheme.headline2,
                      ),
                    ),
                  ),
                  const TextSpan(
                    text: '.',
                  ),
                ],
              ),
            ),
            const SizedBox(
              height: 40.0,
            ),
            TextButton(
              onPressed: () {},
              child: Text(
                'Your age is $age',
                style: const TextStyle(
                  fontSize: 30.0,
                  fontWeight: FontWeight.bold,
                  color: Colors.black,
                  backgroundColor: Colors.yellow,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Without the multi provider it would have become clumsy. Because we had to nest the providers which is not a good practice.

Certainly the multi provider class solves the problem in an elegant manner.

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

Courses at Educative

GitHub repository

Technical blog

Twitter

Comments

One response to “Multi provider flutter in Web App”

  1. […] a result, in the product item controller, we have used Provider.of and Consumer at the same […]

Leave a Reply