{"componentChunkName":"component---src-templates-lesson-post-js","path":"/lesson/future-provider","result":{"data":{"strapiLesson":{"id":"Lesson_104","author":{"email":"eric@ericwindmill.com","username":"Eric Windmill","twitter":"ericwindmill"},"content":"In a nutshell, `FutureProvider` is used to provide a value that might not be ready by the time the widget tree is ready to use it's values. Therefor, the main use-case of `FutureProvider` is to ensure that a null value isn't passed to any widgets. Future provider has a initial value, which widgets can use until the `Future` value is resolved. When resolved, it the `FutureProvider` will tell it's descendents to rebuild, using the new value. \n\nImportantly, this means that the widgets who rely on the value of a future provider will only rebuild once. It will display the initial value, and then the provided future value, and then won't rebuild again. \n\n<div class=\"aside\">\nFuture provider can be configured to change again if there is, for some reason, another new value from the future. But, if you anticipate multiple values from the provider, you should likely be using a `StreamProvider`.\n</div>  \n\nIn this example, I'm going to add onto the previous examples by adding a new class called 'Home'. \n\n```dart\nclass Person {\n  Person({this.name, this.age});\n\n  final String name;\n  int age;\n}\n\n// Classes that will be used with FutureProvider don't need to \n// mixin ChangeNotifier or anything else\nclass Home {\n  final String city = \"Portland\";\n\n  // The value that will be provided must be a `Future`.\n  Future<String> get fetchAddress {\n    // NB: using `Future.delayed` is mocking an HTTP request.\n    // imagine that this is something like http.get(\"http://my_api.com/address\");\n    final address = Future.delayed(Duration(seconds: 2), () {\n      return '1234 North Commercial Ave.';\n    });\n    \n    return address;\n  }\n}\n```\n\nAnd, to provide those classes, we'll just build on previous examples by using a second provider.\n\n```dart\nvoid main() {\n  runApp(\n    // You can wrap multiple providers \n    Provider<Person>(\n      create: (_) => Person(name: 'Yohan', age: 25),\n      // The future provider provides a String value, \n      // rather than the entire claass of Home\n      child: FutureProvider<String>(\n        create: (context) => Home().fetchAddress,\n        // this will be displayed in the meantime\n        // until a new value is provided from the future\n        initialData: \"fetching address...\", \n        child: MyApp(),\n      ),\n    ),\n  );\n}\n```\n\n### Live example\n\n<iframe style=\"height:800px\" src=\"https://dartpad.dev/embed-flutter.html?theme=dark&run=true&split=60&id=9877e8a152f362e7f61174e5c6803cb5\"></iframe>","updated_at":"Wednesday, 5th of August, 2020","slug":"future-provider","strapiId":104,"title":"Future Provider","tutorial":{"category":"Flutter","title":"State Management: Provider"}},"strapiTutorial":{"lessons":[{"author":1,"content":"In the last lesson, we looked at `Consumer`. Before we move back to types of providers, we should look at `Selector`. Selector is similar to consumer, but provides some fine control over when a widgets `build` method is called. In a nutshell, `selector` is a consumer that allows you to define exactly which properties from a model you care about.\n\nFor example, suppose you're working with a `User` class that has 25 properties on it. You don't need to rebuild, or even pass in, a text widget that displays a user name when you update their phone numbers. Selector used for just that.\n\nBecause `Selector` is so similar to `Consumer`, we should just jump into a code example.  \n\n<iframe style=\"height:800px\" src=\"https://dartpad.dev/embed-flutter.html?theme=dark&run=true&split=60&id=2c3dd865bf286490fff5412c052dfd46\"></iframe>\n\nIn my opinion, consumer is probably just fine for most use cases, unless you have an app that's so large that each build is a big deal. That said, this is all moot, because towards the end of this tutorial we will see even better ways to \"consume\" your models.\n","created_at":"2020-07-25T15:08:54.439Z","id":109,"slug":"finer-build-control-with-selector-1","title":"Finer build control with Selector","tutorial":11,"updated_at":"2020-08-05T19:36:11.877Z"},{"author":1,"content":"Half the value of Provider comes from the way it allows you to easily decouple your business logic and inject it into your app. It's also valuable because it allows you to rebuild your UI when your state changes, without any manual work. Thus creating a wonderful union. \n\n[Consumer](https://pub.dev/documentation/provider/latest/provider/Consumer-class.html) is an object in the Provider library that offers a simple API to interact with your provided models in the widgets themselves. In plain English, Consumer exposes instances of provided models, so you can display data and call methods on your provided model.\n\nRecall this previous example:\n\n```dart\nclass MyHomePage extends StatelessWidget {\n  const MyHomePage({Key key}) : super(key: key);\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: const Text('Provider Class'),\n      ),\n      body: Center(\n        child: Text( \n          '''\n          Hi ${Provider.of<Person>(context).name;}!\n          You are ${Provider.of<Person>(context).age} years old''',\n        ),\n      ),  \n      floatingActionButton: FloatingActionButton(\n        onPressed: () => Provider.of<Person>(context, listen: false).increaseAge(),\n      ),\n    );\n  }\n}\n```\n\nHere, we're writing `Provider.of<Person>(context)` three times. In this situation, in which you're interacting with the model quite a bit, this can be simplified using `Consumer`.\n\n### Using consumer\n\nI like this description of Consumer from the [official docs](https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple#changenotifier): \"The Consumer widget doesn't do any fancy work. It just calls Provider.of in a new widget, and delegates its build implementation to builder.\"\n\nPractically, that means that the consumer uses the `builder` pattern that's common with widgets. Using this pattern, the `Consumer` widget exposes some nice objects that make working with the provided models easier. Here's the example above again, but using a `Consumer`:\n\n\n```dart\nclass MyHomePage extends StatelessWidget {\n  const MyHomePage({Key key}) : super(key: key);\n\n  @override\n  Widget build(BuildContext context) {\n    // wrap widgets that need the model in a consumer\n    // consumer.builder callback is passed the person instance\n    // provided by a provider.                \n    return Consumer<Person>(\n      builder: (context, person, _) {\n        return Scaffold(\n          appBar: AppBar(\n            title: const Text('Provider Class'),\n          ),\n          body: Center(\n            child: Text(\n            // now, you can just call 'person.name', et all\n              '''\n            Hi ${person.name}!\n            You are ${person.age} years old''',\n            ),\n          ),\n          floatingActionButton: FloatingActionButton(\n            onPressed: () => person.increaseAge(), // works here too\n          ),\n        );\n      },\n    );\n  }\n}\n```\n\n### Optimizing Consumer\n\nIn the examples so far, you're using the consumer to wrap the entire page. Here, that may be okay because it's:\n - a very small widget tree\n - and multiple children of the Scaffold need access to the `person` instance\n \nIn a robust app this may be undesirable. The entire page is rebuilding every time any widget in the page is rebuilt. If there are hundreds of widgets in your tree, you might see a performance hit. Consumer offers a way to solve this problem, as well.\n\nThe obvious way, I guess, to solve this would be to wrap a consumer around each of the individual widgets that need it. But, that brings us back to the inconvenience we were trying to solve in the first place (robust, repeated code). A better way to solve that is by using the `Consumer.child` argument in tandem with the `builder`.\n\nI had to tweak the code, and here's an improved live example:\n \n\n<iframe style=\"height:800px\" width=\"100%\" src=\"https://dartpad.dev/embed-flutter.html?theme=dark&run=true&split=60&id=b11fc6602f5156543fddfd7041dd5aa2\"></iframe>\n\nSo, what's going on here? The `child` widget passed to `Consumer` is built on it own, outside of the `builder` callback. It is then _passed into_ the builder as it's third argument. While this API may look a little wonky, it's pretty impressive. It allows the child widget to go on livin', without being rebuilt, while all the widgets defined in the builder callback do get rebuilt. Wow.\n\nAgain, the API might seem confusing, because it looks like the consumer now has two properties that build the widget tree below this Consumer. But, once you get used to looking at this, it's not a big deal. And totally worth the benefits.\n\n ","created_at":"2020-07-25T15:03:59.665Z","id":102,"slug":"rebuilding-widgets-with-consumer","title":"Rebuilding widgets with Consumer","tutorial":11,"updated_at":"2020-08-05T19:36:11.877Z"},{"author":1,"content":"\n[`StreamProvider`](https://pub.dev/documentation/provider/latest/provider/StreamProvider-class.html) provides, well, Streamed values. Like FutureProvider, provided values will be auto-magically passed the new values of the provided value as they come in. The major difference is that the values will trigger a re-build as many times as it needs to. \n\n<div class=\"aside\">\n    If you need a refresher on Streams, I recommend you  <a href=\"https://ericwindmill.com/articles/async_dart_flutter/\">check out my code-cartoon of Dart Streams</a>, or find a whole chapter about Streams in my book <a href=\"bit.ly/flutterinaction\">Flutter in Action</a>. Streams can be hard to grasp (and implement) if you aren't familiar, but they're wildly useful and popular in the Flutter ecosystem.\n</div>\n\n\n`StreamProviders` work so similarly to `FutureProvider`, that we should just jump straight into code. First, setting up the stream:\n\n```dart\nclass Person {\n  Person({this.name, this.initialAge});\n\n  final String name;\n  final int initialAge;\n\n  // A StreamProvider's only requirement is that, well,\n  // you give it a stream value.\n  // This [generator] function will _yield_ a new number every second.\n  Stream<String> get age async* {\n    var i = initialAge;\n    while (i < 85) {\n      await Future.delayed(Duration(seconds: 1), () {\n        i++;\n      });\n      yield i.toString();\n    }\n  }\n}\n```\n\n## Live Example\n\n<iframe height=\"800px\" width=\"100%\" src=\"https://dartpad.dev/embed-flutter.html?theme=dark&run=true&split=60&id=59c25f7f9b44c740b033ed1bc36101cf\"></iframe>\n\n","created_at":"2020-07-25T15:06:42.585Z","id":106,"slug":"stream-provider","title":"Stream Provider","tutorial":11,"updated_at":"2020-08-06T16:20:15.289Z"},{"author":1,"content":"In a nutshell, `FutureProvider` is used to provide a value that might not be ready by the time the widget tree is ready to use it's values. Therefor, the main use-case of `FutureProvider` is to ensure that a null value isn't passed to any widgets. Future provider has a initial value, which widgets can use until the `Future` value is resolved. When resolved, it the `FutureProvider` will tell it's descendents to rebuild, using the new value. \n\nImportantly, this means that the widgets who rely on the value of a future provider will only rebuild once. It will display the initial value, and then the provided future value, and then won't rebuild again. \n\n<div class=\"aside\">\nFuture provider can be configured to change again if there is, for some reason, another new value from the future. But, if you anticipate multiple values from the provider, you should likely be using a `StreamProvider`.\n</div>  \n\nIn this example, I'm going to add onto the previous examples by adding a new class called 'Home'. \n\n```dart\nclass Person {\n  Person({this.name, this.age});\n\n  final String name;\n  int age;\n}\n\n// Classes that will be used with FutureProvider don't need to \n// mixin ChangeNotifier or anything else\nclass Home {\n  final String city = \"Portland\";\n\n  // The value that will be provided must be a `Future`.\n  Future<String> get fetchAddress {\n    // NB: using `Future.delayed` is mocking an HTTP request.\n    // imagine that this is something like http.get(\"http://my_api.com/address\");\n    final address = Future.delayed(Duration(seconds: 2), () {\n      return '1234 North Commercial Ave.';\n    });\n    \n    return address;\n  }\n}\n```\n\nAnd, to provide those classes, we'll just build on previous examples by using a second provider.\n\n```dart\nvoid main() {\n  runApp(\n    // You can wrap multiple providers \n    Provider<Person>(\n      create: (_) => Person(name: 'Yohan', age: 25),\n      // The future provider provides a String value, \n      // rather than the entire claass of Home\n      child: FutureProvider<String>(\n        create: (context) => Home().fetchAddress,\n        // this will be displayed in the meantime\n        // until a new value is provided from the future\n        initialData: \"fetching address...\", \n        child: MyApp(),\n      ),\n    ),\n  );\n}\n```\n\n### Live example\n\n<iframe style=\"height:800px\" src=\"https://dartpad.dev/embed-flutter.html?theme=dark&run=true&split=60&id=9877e8a152f362e7f61174e5c6803cb5\"></iframe>","created_at":"2020-07-25T15:05:20.814Z","id":104,"slug":"future-provider","title":"Future Provider","tutorial":11,"updated_at":"2020-08-05T19:36:11.877Z"},{"author":1,"content":"\nIn the `FutureProvider` lesson, you may have noticed something ugly.\n\n```dart\nvoid main() {\n  runApp(\n    Provider<Person>(\n      create: (_) => Person(name: 'Yohan', age: 25),\n      child: FutureProvider<String>(\n        create: (context) => Home().fetchAddress,\n        initialData: \"fetching address...\", \n        child: MyApp(),\n      ),\n    ),\n  );\n}\n```\n\nThere are two providers, one nested inside the over. You can imagine this getting quickly out of hand:\n\n```dart\nvoid main() {\n  runApp(\n    // You can wrap multiple providers \n    Provider<Person>(\n      create: (_) => Person(name: 'Yohan', age: 25),\n      child: FutureProvider<String>(\n        create: (context) => Home().fetchAddress,\n        initialData: \"fetching address...\", \n        child: StreamProvider<Connectivity>(\n          create: (context) => Session.connectivity(),\n          child: ChangeNotifierProvider<AuthState>(\n            create: (context) => Session.authState(),\n            child: MyApp(),\n         ),\n        ),\n      ),\n    ),\n  );\n}\n```\n\nThis isn't super readable. Provider includes a fix for this: [MultiProvider](https://pub.dev/documentation/provider/latest/provider/MultiProvider-class.html).\n\n`MultiProvider` let's you pass in a list of providers without nesting anything,\n\n```dart\nvoid main() {\n  runApp(\n    // You can wrap multiple providers \n    MultiProvider(\n      providers: [\n        Provicer<Person>(create: (_) => Person(name: 'Yohan', age: 25)),\n        FutureProvider<String>(create: (context) => Home().fetchAddress),\n      ],\n      child: MyApp(),\n    ),\n  );\n}\n```\n\nThis widget just makes code more terse and readable. Which is always nice.\n\n<div class=\"aside\">\nIf you really want to be impressed by the creator of Provider, <a href=\"https://github.com/rrousselGit\">Remi</a>, check out his package called <a href=\"https://pub.dev/packages/nested\">nested</a>, which provides widgets that can take a list of children and nest them. This is what `MultiProvider` is built on top of.  \n</div>","created_at":"2020-07-25T15:06:10.841Z","id":105,"slug":"multi-provider-micro-lesson","title":"MultiProvider micro lesson","tutorial":11,"updated_at":"2020-08-05T19:36:11.877Z"},{"author":1,"content":"Most of the examples you'll see on the internets is using the [ChangeNotifierProvider](https://pub.dev/documentation/provider/latest/provider/ChangeNotifierProvider-class.html), and it's also the class you'll likely use most often. This class is basically a provider-wrapper over a class that implements `ChangeNotifier`.\n\nAccording to the [Flutter docs](https://api.flutter.dev/flutter/foundation/ChangeNotifier-class.html), a `ChangeNotifier` is 'a class that can be extended or mixed in that provides a change notification API using VoidCallback for notifications.' In practical terms, other objects can _listen_ to a `ChangeNotifier` object. And, when the change notifier gets updated values, it can call a method called 'notifyListeners()', and then any of it's listeners will respond with an action. Listening to a change notifier is done by registering a callback, which is called when `notifyListeners` is invoked.\n\nThat description felt a bit esoteric, so let's just look at a quick `ChangeNotifier` example _without Provider_.\n\n```dart\nclass Person with ChangeNotifier {\n  Person({this.name, this.age});\n\n  final String name;\n  int age;\n\n  // when `notifyListeners` is called, it will invoke\n  // any callbacks that have been registered with an instance of this object\n  // `addListener`.            \n  void increaseAge() {\n    this.age++;\n    notifyListeners();\n  }\n}\n\nvoid main() {\n  var person = Person('Yohan', 25);\n  \n  // `addListener` is a method on the `ChangeNotifier` class,\n  // which is mixed-in to the Person class    \n  person.addListener(() {\n    print('value updated!: ${person.age}')\n  });      \n\n  person.increaseAge();  // 26\n}\n```\n\nIn this example, we've started listening to the `Person with ChangeNotifier` class by calling `addListener`, which accepts a `VoidCallback` function as it's argument. When the age is increased, it will execute that callback. \n\n<div class=\"aside\">\n    ChangeNotifier is built into the Flutter SDK, and it's \"purpose\" is to call `notifyListeners` whenever data changes that should in turn update your UI. In the example above, I am not using it in widgets, but it's important to note that this class is not available in other Dart environments.\n</div>\n\nThis is one way to encapsulate the state of your app inside of classes, but it presents a problem... if you wanted to use it in multiple widgets in different branches in your widget tree, it would quickly make your code super hairy and difficult to refactor. You'd basically be passing an instance of your `ChangeNotifier` all around the widget tree manually.\n\nBut, that is the _exact_ problem that `provider` solves.\n\n### ChangeNotifierProvider\n\nThis example is not going to be much different than the previous Provider lesson. The `ChangeNotifierProvider` is used exactly like the vanilla Provider. Let's start with the code, and they'll I'll highlight some important points.\n\nFirst, add the provider to the tree:\n\n```dart\nclass Person with ChangeNotifier {\n  Person({this.name, this.age});\n\n  final String name;\n  int age;\n\n  void increaseAge() {\n    this.age++;\n    notifyListeners();\n  }\n}\n\n// here, you can see that the [ChangeNotifierProvider]\n// is \"wired up\" exactly like the vanilla [Provider]\nvoid main() {\n  runApp(\n    ChangeNotifierProvider(\n      create: (_) => Person(name: \"Yohan\", age: 25),\n      child: MyApp(),\n    ),\n  );\n}\n```\n\nAs you can see, wiring up a ChangeNotifierProvider is exactly the same as the Provider example from the previous lesson. Using it in widget tree is going to be similar:\n\n<div class=\"aside\">\nThe example I'm about to show you is the _most basic_ example, and probably not exactly how you'd consume the data from provider in your real app. That will be covered in the next lesson, so don't @ me.\n</div>\n\n```dart\nclass MyHomePage extends StatelessWidget {\n  const MyHomePage({Key key}) : super(key: key);\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: const Text('Provider Class'),\n      ),\n      body: Center(\n        child: Text( \n          // reading this data is exactly like it was in\n          // the previous lesson             \n          '''\n          Hi ${Provider.of<Person>(context).name;}!\n          You are ${Provider.of<Person>(context).age} years old''',\n        ),\n      ),  \n      floatingActionButton: FloatingActionButton(\n        // this is where there's a difference.\n        // when the FAB is tapped, it will call `Person.icreaseAge()` on the\n        // person instance that was created by provider.     \n        onPressed: () => Provider.of<Person>(context, listen: false).increaseAge(),\n      ),\n    );\n  }\n}\n```\n\nTwo important notes about that code:\n\n- Because this is a `ChangeNotifier`, the UI will re-build and the age will be increased. (Success!)\n- You may have noticed `listen: false` in the `of` method. The `listen: false` parameter is _mandatory_ whenever you're using Provider to fetch an instance and call a method on that instance. This has a practical application, though. Because you aren't listening, the widget doesn't need to re-render just because a change was made. In this example, there would be no reason to re-render the FloatingActionButton, even when the ChangeNotifier did notify it's listeners.\n\nFinally, just so you believe me, let's look at this running in a Flutter app:\n\n<iframe style=\"height:800px\" src=\"https://dartpad.dev/embed-flutter.html?theme=dark&run=true&split=60&id=54820e0eab2670dc24bd7354a0766bc8\"></iframe>","created_at":"2020-07-25T15:03:29.864Z","id":101,"slug":"change-notifier-provider","title":"ChangeNotifierProvider","tutorial":11,"updated_at":"2020-08-05T19:36:11.877Z"},{"author":1,"content":"ProxyProvider is the tough to grok at first, but it's quite useful. It let's you pass values from one provided model to another, to create a value from two (or more) providers.\n\n![proxy provider cartoon](https://res.cloudinary.com/duqbhmg9i/image/upload/c_scale,h_800/v1590180537/flutter_by_example/proxy_provider_bwrvtq.jpg)\n\nRight off the bat, here's some things to keep in mind before looking at the code:\n\n- There are several kinds of ProxyProviders, which are proxy versions of the standard providers they resemble:\n    - ProxyProvider\n    - ChangeNotifierProxyProvider\n    - ListenableProxyProvider\n- You can use up to 6 providers to combine values, but you must use the following classes to specify the number of providers that will be passing values into the proxy:\n    - ProxyProvider0 (the base class)\n    - ProxyProvider2 (pass values from 2 providers into the proxy)\n    - ProxyProvider3\n    - ProxyProvider4\n    - ProxyProvider5\n    - ProxyProvider6\n    \nThose same classes exist for `ChangeNotifierProvider` and `ListenableProxyProvider`.\n\n### Using Proxy Provider\n\nExplaining the proxy provider in words is pretty esoteric and hard to grok, so let's look at some code. In the following example, our example friend 'Yohan' is growing up, and it's time for him to get a job. I am providing a `Person` object to the widget tree, and also a `Job` object. A `Job` requires a person for initialization.\n\nIn this situation, the `Job` is the _proxy_. Which means that the Job is the object you'll likely want to interface with, but it's values rely on the person, so that will be exposed as well.\n\nNB: It's important to note that you still _can_ interact with the person if you'd like, and you don't _have_ to expose the person via the job instance.\n\nIn this example, Yohan has made a digital business card. And, the he wants the business card to automatically change it's title when he gets older and graduates, and starts his career. The set-up follows:\n\n\n```dart\nclass Person with ChangeNotifier {\n  Person({this.name, this.age});\n\n  final String name;\n  int age;\n\n  void increaseAge() {\n    this.age++;\n    notifyListeners();\n  }\n}\n\nclass Job with ChangeNotifier {\n  Job(\n    this.person, {\n    this.career,\n  });\n\n  final Person person;\n  String career;\n  String get title {\n    if (person.age >= 28) return 'Dr. ${person.name}, $career PhD';\n    return '${person.name}, Student';\n  }\n}\n\nvoid main() {\n  runApp(\n    MultiProvider(\n      providers: [\n        // you must first provider the object that will be passed to the proxy    \n        ChangeNotifierProvider<Person>(create: (_) => Person(name: 'Yohan', age: 25)),\n        // Because the ChangeNotifierProxyProvider is being used,\n        // each class used must be of ChangeNotifier type    \n        ChangeNotifierProxyProvider<Person, Job>(\n          // first, create the _proxy_ object, the one that you'll use in your UI\n          // at this point, you will have access to the previously provided objects                \n          create: (BuildContext context) => Job(Provider.of<Person>(context, listen: false)),\n          // next, define a function to be called on `update`. It will return the same type\n          // as the create method.   \n          update: (BuildContext context, Person person, Job job) => Job(person, career: 'Vet'),\n        ),\n      ],\n      child: MyApp(),\n    ),\n  );\n}\n``` \n\nAs you can see, the set up is a bit more involved, perhaps. But, it's still quite terse and easy to read. And, in the following example, you'll see how easily it's used.\n\n<iframe style=\"height:800px\" width=\"100%\" src=\"https://dartpad.dev/embed-flutter.html?theme=dark&run=true&split=60&id=0de0984c6f057a14c17fdfc6568114c7\"></iframe>\n\nThe neat thing here to look for is that all three values that are _read_, are done via the provided `job` object, but the button calls the `Person.increaseAge` method when pressed. Yet, the UI still knows to rebuild when the `Job.title` value is different.","created_at":"2020-07-25T15:08:17.154Z","id":108,"slug":"proxy-provider","title":"ProxyProvider","tutorial":11,"updated_at":"2020-08-05T19:36:11.877Z"},{"author":1,"content":"[Provider](https://github.com/rrousselGit/provider) can be somewhat difficult to explain. The package author, [Remi](https://github.com/rrousselGit), has described it as a mix between State Management and Dependency Injection. At his talk at [Flutter Europe in 2019](https://www.youtube.com/watch?v=BulIREvHBWg), he quoted another Flutter community usual, [Scott Stoll](https://twitter.com/scottstoll2017), who called is 'Inherited Widgets for humans'. I think this is the most straight-forward explanation.\n\nI also find it difficult to find an explanation on the interwebs that includes an easy to grok example. If you want to use provider effectively, you're left to tinkering or reading the source code. I will attempt to fill that void here. \n\nIn a nutshell, Provider gives us an easy, low boiler-plate way to separate business logic from our widgets in apps. Because it's built on `InheritedWidget` classes, it also makes it easy to re-use and re-factor business logic. Separating state from your UI is one of the main problems that Provider solves.\n\n### What does Provider do for me? \n\nIt can be used in a variety of ways in your Flutter app. It can be used in-lieu of more robust state-management libraries, or along side them. It can be used with `InheritedWidgets` and `StatefulWidgets`, or again, in place of them. It \"does\" two jobs:\n\n- Separates your state from your UI\n- Manages rebuilding UI based on state changes\n\nWhich makes loads of things simpler, from reasoning about state, to testing to refactoring. It makes your codebase _scalable_.\n\nConsider this widget tree that uses no libraries at all:\n\n<!-- widget tree image -->\nThis widget tree is an extremely crude version of the `Counter` app we all know and love. It passes a callback (`onPressed`) to a `FloatingActionButton` and a `counter` property down a text widget. When `onPressed` is fired, it updates the counter. \n![counter app widget tree](https://res.cloudinary.com/duqbhmg9i/image/upload/c_scale,h_673/v1590101648/flutter_by_example/widget_tree_0_no_provider_cv4dap.png)\n\nThat's fine, but what happens when you need to refactor your code? What happens if state is shared between different widgets?  And what about testing? Your logic is sprinkled throughout your app, and tied to your widgets. This makes writing tests a pain, verbose, and hard to refactor.\n\nImagine for a moment that you decided you no longer wanted a FloatingActionButton, and you wanted a button, as a child of the column, to trigger `onPressed`. That refactor would be a pain. \n\n(I know my drawing... err... leaves a lot to be desired. But the gist is that all of the pink text is what would have to be refactored.)\n\n![refactoring the widget tree](https://res.cloudinary.com/duqbhmg9i/image/upload/c_scale,h_673/v1590101648/flutter_by_example/widget_tree_2_no_provider_c59lkm.png)\n\nBut there's a better way. (To be fair, this can be done with just plain ol InheritedWidgets as well, but provider has a nicer API and less boiler plate.) \n\n(Disclaimer! A provided widget _is_ in the widget tree, but I drew it separately because I feel it's helpful to think of them as different entities.)\n\n<!-- image of provider on one side and widget tree on the other -->\n ![widget tree with provider](https://res.cloudinary.com/duqbhmg9i/image/upload/c_scale,h_673/v1590101650/flutter_by_example/widget_tree_w_provider_fupfto.png)\n\nIf you're using this architecture, you can have any widget in the tree read the Counter and trigger counter methods. Refactor away, because it's much easier. And, you can test the logic of the counter with a simple unit test, no need to bring the the UI into it.\n\n### Is provider a State Management library?\n\nIn my opinion, no. But it can be. \n\nUnlike libraries like Redux and Bloc, Provider simply provides tools to 'wire up' our UI to business logic, and it is not opinionated in how you manage state. Because of this, it's almost easier to look at it as Flutter-specific dependency injection library (and that's what it was originally advertised as). In fact, the Bloc library is built on top of provider, because provider, again, doesn't _really_ manage state for you.\n\nProvider helps make your widgets as 'dumb' as possible by separating logic from the widgets, and injecting the important data to those widgets. If you're building an e-commerce app, you can build a _cart page_ that knows it should display some items in a cart. But, using provider, the widget has no concept of what those items are, nor is it responsible for keeping track of the cart contents. Rather, there would be a separate class elsewhere in your app, perhaps called `Cart`, that manages all the logic. And, whenever a new item is added the the cart, the widget that displays the cart item is told to re-render with the new items.\n\nIf this seems hand-wavy and obtuse, the examples on the following pages should help make this more concrete (as well as show you what you really want: _how_ to use provider with real life code). \n\nBut lastly, I need to point out a few important points to remember while using provider:\n\n* Provider is built using widgets. It literally creates new widget subclasses, allowing you to use all the objects in provider as if they're just part of Flutter. This also means that provider is _not_ cross platform. (By cross platform, I mean outside of a Flutter project. i.e. AngularDart)\n* Separating this business logic makes your code much easier to test and maintain.\n* Again, Provider is not opinionated about state management. It is not going to force consistency like Redux would.\n\n\nThe remainder of this tutorial will walk through the usage of Provider by walking through how you'd use most of the different classes in Provider.","created_at":"2020-07-25T15:01:45.156Z","id":99,"slug":"what-is-provider","title":"What is Provider?","tutorial":11,"updated_at":"2020-08-05T19:36:11.877Z"},{"author":1,"content":"The content of this lesson could be filed under \"extraneous\". You don't need to know this in order to use Provider. No more than you need to know how Skia works to build a Flutter app. But, you might learn something neat. I will also spend some time gushing about how cool Provider is, and how well designed it is. This was not my intention, but it happened.\n\nSome background: In order to learn Provider, I basically 'rebuilt it', using the original package as a guide. This is how I like to learn the ins and outs. While taking on that venture, I learned a lot of interesting things about both Flutter and Provider. Things that I have read before, and make sense logically, but really 'clicked' when I saw how they were implemented. \n\nSo, I've decided to do a short write up of how Provider works for the curious out there. \n\n<div class=\"disclaimer\">\nThis is 100% information that I have deduced, without any confirmation from the real experts, such as the package author. So, take this all with a grain of salt.\n</div>\n\n### A Flutter detour\n\nBefore I get in the weeds, I want to take a little detour to and talk about how Flutter builds (and rebuilds) UI.\n\nAs you may know, you (the Flutter developer) can tell Flutter to rebuild your UI by calling `setState`. You can also manage when your UI updates with other methods on the `State` object, such as `didChangeDependencies`. But, it all comes down to the `State` object. (`StatelessWidget`, on the other hand, are rebuilt when they're changed by configuration changes passed into them.)\n\nWhat you may not know is that widgets are just \"configuration\" or blue-prints for different objects called `Elements`. And, when you call `setState`, your widget is interfacing with a singular Element, and not the Flutter or the widget tree itself. It's the Element's responsibility to tell Flutter that it has changed, and it needs to be repainted. This is done this via a method called `markNeedsBuild`, which is called internally.\n\nThis matters to us (provider users) because all objects in Provider are widgets (and elements). They know how to interface with Flutter. Which means you don't have to call `setState` if you're using Provider properly, because its toolbox of widgets are handling all of that for you. This is an important piece of Provider's design.\n\n### Providers are widgets\n\nIf you read any docs, you will surely understand that all classes in Provider are implementations of different widgets. I read this over and over again, but just kind of \"glossed over it\", and didn't really internalize the implications. But, I'll say it here anyway: Providers are widgets! And that's primarily what I want to talk about in this lesson. \n\nWhen I started reading Provider source code, I was immediately overwhelmed by the number of classes, mixins, extensions and interfaces that are in that library. There are typedefs abound, to boot. I wrapped my head around it by creating a chart of sorts that describes the class structure of Provider. It looks like this:\n\n(I don't expect you to be able to read this)\n<!-- full screen shot -->\n![provider class hierarchy](https://res.cloudinary.com/duqbhmg9i/image/upload/c_scale,h_741/v1590094616/flutter_by_example/Provider_1_g8iahe.jpg)\n\nKeep in mind that the only Provider that this document includes is the base `Provider` class. I haven't included FutureProvider, StreamProvider, Consumer, Selector, etc.\n\nThe big text that you _can_ read in this image is \"Element Tree\" and \"Widget Tree\". This seems like a good place to start. \n\n<!-- element tree --> \nThe element tree:\n![element tree](https://res.cloudinary.com/duqbhmg9i/image/upload/c_scale,h_1000/v1590094616/flutter_by_example/Provider_2_plmcy1.jpg)\n\nThe widget tree:\n![widget tree](https://res.cloudinary.com/duqbhmg9i/image/upload/c_scale,h_1000/v1590094616/flutter_by_example/Provider_3_qzrmh0.jpg)\n\nAll these charts may only make sense to me, but let me point out some interesting insights:\n\n1. These classes aren't just Widget types, they're widgets built from the ground up. They include custom `Element` types. They are literally custom implementations of objects that Flutter can work with, and they don't rely on  `InheritedWidget` or under the hood. This is impressive, _and_ powerful.\n2. Much of the classes are exposed to us, the developers. Specifically interesting is `InheritedProvider`, which all providers are subclasses of. (Again, my chart only shows `Provider`, but you'll have to trust me on this one.) This means that just like you can build your own widgets in Flutter, Provider is implemented in a way that you can build your `Providers`. Truly following the Flutter pattern that we all know and love.\n3. Provider even includes its own `BuildContext` sub class, which is why we can work with Provider so seamlessly in the widget tree.\n4. `InheritedProvider` classes do have a concept of `State` (via the `_Delegate` objects), which seems to be one of the reasons that we can use these inherited widget-esque objects with so little boiler plate. Previous to this package, using InheritedWidget's for responsive state management involved combining inherited widgets and stateful widgets, which of course means a ton of boiler plate.\n\n### final thoughts\n\nProvider is truth.","created_at":"2020-07-25T15:11:19.002Z","id":112,"slug":"for-the-curious-how-is-provider-implemented","title":"For the curious: How is provider implemented","tutorial":11,"updated_at":"2020-08-05T19:36:11.877Z"},{"author":1,"content":"In order to showcase the real, core value proposition of provider, I will show you the simplest example Flutter app I can build. To be sure, we will see some complex and \"real world\" examples through-out this section, but at it's core, Provider just tells Flutter apps how to interact with non-widget data classes. \n\nFirst, I want to show the example, and then I will walk through the code showing and explain what's going on.\n\n<iframe style=\"height:800px\" src=\"https://dartpad.dev/embed-flutter.html?theme=dark&run=true&split=60&id=67ab0272443d5248388a3fcc0afb647f\"></iframe>\n\nThat's it. It's just an app that displays some text on the screen. Now, let's walk through the code.\n\n```dart \n// This class is what Provider will work with.\n// It will _provide_ an instance of the class to any widget\n// in the tree that cares about it. \nclass Person {\n  Person({this.name, this.age});\n\n  final String name;\n  final int age;\n}\n\n// Here, we are running an app as you'd expect with any Flutter app\n// But, we're also wrapping `MyApp` in a widget called 'Provider'\n// Importantly, `Provider` is itself a widget, so it can live in the widget tree.\n// This class uses a property called `create` to make an instance of `Person`\n// whenever it's needed by a widget in the tree.\n// The object returned by the function passed to `create` is what the rest of our app\n// has access to. \nvoid main() {\n  runApp(\n    Provider(\n      create: (_) => Person(name: \"Yohan\", age: 25),\n      child: MyApp(),\n    ),\n  );\n}\n\n\n// Just a plain ol' StatelessWidget\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return const MaterialApp(\n      home: MyHomePage(),\n    );\n  }\n}\n\n// Again, just a stateless widget\nclass MyHomePage extends StatelessWidget {\n  const MyHomePage({Key key}) : super(key: key);\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: const Text('Provider Class'),\n      ),\n      body: Center(\n        child: Text(\n          // this string is where we use Provider to fetch the instance\n          // of `Person` created above in the `create` property\n          '''\n          Hi ${Provider.of<Person>(context).name}!\n          You are ${Provider.of<Person>(context).age} years old''',\n        ),\n      ),\n    );\n  }\n}\n```\n\nFor the most basic example, that's all you need. Provider simply exposes an instance of an object to all it's descendent widgets via 'Provider.of<T>(context)'. \n\n<div class=\"aside\">\nIn Dart, it's convention to use `T` as a generic type. When you see `Provider.of<T>(context)`, \"T\" is indicating that a type argument is required. For example, `Provider.of<User>(context)` would be used to indicate you're referring to a `User` object. This is no different than defining collections. For example, a list of strings is defined by writing `List<String> myList = []`.\n</div>\n\nIf you're familiar with [InheritedWidget](https://api.flutter.dev/flutter/widgets/InheritedWidget-class.html) objects, then this should look familiar. And that's because Provider is, in a nutshell, a widget that behaves exactly like the `InheritedWidget`, but with far less boiler plate. (If you aren't familiar, you may want to follow that link and learn a little bit.)\n\nIf you take anything from this lesson, I hope that it's this: Provider just... err... _provides_ classes to your widget tree that aren't widgets.\n\nThis example shows the most basic example, in which you can only read data. You can't update data. And even if you could, it wouldn't cause the widget tree to re-render, because there's nothing telling Flutter that the data has changed. Luckily, Provider includes a whole swath of classes that can help you with this which we'll explore in the following lessons.","created_at":"2020-07-25T15:02:34.380Z","id":100,"slug":"the-most-basic-example-using-provider","title":"The most basic example using Provider","tutorial":11,"updated_at":"2020-08-05T19:36:11.877Z"},{"author":1,"content":"There is no new information here, but rather an app that uses multiple providers, over multiple screens. That in mind, this lesson is broken down into two parts: the full app, running in DartPad, followed by some explanations for some of the parts that may be harder to grok.\n\n<iframe style=\"height:800px\" src=\"https://dartpad.dev/embed-flutter.html?theme=dark&run=true&split=60&id=b0cdc975cdb48076fc3016586693b92c\"></iframe>\n\n### Breaking down interesting parts\n\nThe app isn't all that interesting, but there are a few code examples that will help drive home the ideas of provider.\n\n- First, let's take a look at the models, so the rest of the code makes sense\n\n```dart\n// The product class does nothing fancy\nclass Product {\n  final String name;\n  final double cost;\n\n  Product({this.name, this.cost});\n}\n\n// This class tracks the products that \n// the user wants to buy, and it's a [ChangeNotifier]\nclass Cart with ChangeNotifier {\n  List<Product> products = [];\n\n  double get total {\n    return products.fold(0.0, (double currentTotal, Product nextProduct) {\n      return currentTotal + nextProduct.cost;\n    });\n  }\n\n  void addToCart(Product product) => products.add(product);\n  void removeFromCart(Product product) {\n    products.remove(product);\n    notifyListeners();\n  }\n}\n\n// The user class does nothing fancy.\nclass User {\n  final String name;\n  final Cart cart;\n\n  User({this.name, this.cart});\n}\n\nclass Store {\n  // Perhaps we're going to use a StreamProvider?\n  StreamController<List<Product>> _streamController = StreamController<List<Product>>();\n  Stream<List<Product>> get allProductsForSale => _streamController.stream;\n  \n  // rest of class\n}\n\n// This class is a singleton that mocks out two pieces of functionality:\n// Logging in a user\n// And fetching products from a realtime data base (like FireStore)\nclass MockDatabase {\n  static final MockDatabase _instance = MockDatabase._internal();\n\n  factory MockDatabase() {\n    return _instance;\n  }\n\n  MockDatabase._internal();\n\n  Future<User> login() async {\n    return await Future.delayed(Duration(seconds: 1), () {\n      return User(name: 'Yohan', cart: Cart());\n    });\n  }\n\n  // Imagine this is like calling Firestore.get('products').listen(...);\n  // Anytime there are new products in the databse, they'll be pushed down\n  // to the app.\n  Stream<List<Product>> getProductsBatched() async* {\n    List<Product> allProducts = [];\n\n    var i = 0;\n    while (i < 10) {\n      await Future.delayed(Duration(seconds: 1), () {\n        allProducts.add(_productsInDatabase[i]);\n      });\n      i++;\n      yield allProducts;\n    }\n  }\n  // rest of class...\n\n}\n\n```\n\n- The app starts with a `MultiProvider` to provide some models to the entire app.\n\n```dart\nvoid main() async {\n  // creating a use right off the bat is \n  // contrived so I can use a `.value` constructor.\n  final user = await MockDatabase().login();\n\n  runApp(\n    MultiProvider(\n      providers: [\n        // The user provider uses a value constructor because the value\n        // already exists, and we want to make sure we're using the same user\n        Provider<User>.value(value: user),\n\n        // Store and Cart are both needed on the home page,\n        // so they're provided right off the bat\n        Provider<Store>(create: (_) => Store()),\n        ChangeNotifierProvider<Cart>(create: (_) => Cart()),\n      ],\n      child: MyApp(),\n    ),\n  );\n}\n```\n\nNothin' too fancy there. Let's move into the `Scaffold.body` property of the `build` method for the `ProductsPage`, where we're going to use a `StreamProvider`\n\n```dart\n// The StreamProvider is providing a single property from the Cart,\n// not the Cart itself. Thus, StreamProvider<List<Product>>\nbody: StreamProvider<List<Product>>(\n  initialData: [],\n  // using Provider to fetch a model and return a property from it? Fancy!\n  create: (_) => Provider.of<Store>(context).allProductsForSale,\n  catchError: (BuildContext context, error) => <Product>[],\n  // List equality has nothing to do with the elements in the list\n  // Therefor, in order to tell Flutter that list has changed, we need to compare a \n  // property of the list that will be different when elements are added or removed.\n  updateShouldNotify: (List<Product> last, List<Product> next) => last.length == next.length,\n  builder: (BuildContext context, Widget child) {\n    final items = context.watch<List<Product>>(); // context.watch rules\n    return ListView.builder(\n      itemCount: items.length,\n      itemBuilder: (BuildContext context, int index) {\n        if (items.isEmpty) {\n          return Text('no products for sale, check back later');\n        }\n        final item = items[index];\n        return ListTile(\n          title: Text(item.name ?? ''),\n          subtitle: Text('cost: ${item.cost.toString() ?? 'free'}'),\n          trailing: Text('Add to Cart'),\n          onTap: () {\n            // notice that this calls a method on `Cart`, \n            // but Cart isn't used anywhere else on this page.\n            // This is an example of one model being shared across screens,\n            // And I promise its far easier than passing values from one \n            // screen to another during navigation\n            context.read<Cart>().addToCart(item);\n          },\n        );\n      },\n    );\n```\n\n- Lastly, let's peak at the other page:\n\n```dart\nclass CartPage extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: Text(context.watch<User>().name + 's Cart'),\n      ),\n      // Consumer + a ChangeNotifier (cart) will ensure that \n      // That this portion of the tree rebuilds when Cart.notifyListeners() is called.\n      body: Consumer<Cart>(\n        builder: (BuildContext context, Cart cart, Widget child) {\n          return Column(\n            children: <Widget>[\n              Expanded(\n                child: ListView.builder(\n                  itemCount: cart.products.length,\n                  itemBuilder: (BuildContext context, int index) {\n                    if (cart.products.isEmpty) {\n                      return Text('no products in cart');\n                    }\n                    final item = cart.products[index];\n                    return ListTile(\n                      title: Text(item.name ?? ''),\n                      subtitle: Text('cost: ${item.cost.toString() ?? 'free'}'),\n                      trailing: Text('tap to remove from cart'),\n                      onTap: () {\n                        // context.read is the easiest way to call \n                        // methods on a provided model\n                        context.read<Cart>().removeFromCart(item);\n                      },\n                    );\n                  },\n                ),\n              ),\n              Divider(),\n              Align(\n                alignment: Alignment.centerRight,\n                child: Text(\n                  // remember, context.select allows you to \n                  // listen to specific properties, and ignore the rest of a class\n                  'TOTAL: ${context.select((Cart c) => c.total)}',\n                  style: Theme.of(context).textTheme.headline3,\n                ),\n              )\n            ],\n          );\n        },\n      ),\n    );\n  }\n}\n```\n\nHopefully this slightly more robust example shows you how different classes from Provider all work along side each-other, even across pages. \n\nBut, that's it. You've solved my Provider puzzle! Checkout [Provider docs](https://pub.dev/packages/provider) for even more classes and updates to the package.","created_at":"2020-07-25T15:10:34.826Z","id":111,"slug":"the-final-example-a-shopping-cart-app","title":"The final example (A shopping cart app)","tutorial":11,"updated_at":"2020-08-05T19:36:11.877Z"},{"author":1,"content":"If you've used Provider at all in the past, then you may have noticed that all types of `Provider` classes have two constructors: the default constructor, and a `.value` named constructor.\n\nThese constructors, which I'll call _value constructors_, have specific use-cases. In the examples you've seen so far the `.value` constructors wouldn't be what you want. \n\nIn general, you want to use value constructors when you already have an instance of a class you'd like to provide. Say you're providing a `Person` instance that has already been created for some other reason. If you pass that variable into a provider, it's possible that the provider will dispose of that object while other pieces of code are still using it. \n\nFor example:\n\n```dart\nPerson person = Person();\n\nChangeNotifierProvider<Person>(\n  create: (_) => person; // bad!\n)\n``` \n\nIf that person variable is used anywhere else, it may cause errors when this widget is removed from the tree. The reverse of this set-up is also a problem. Consider this example:\n\n```dart\n// this is bad! \n// everytime this widget is rebuilt, it will create a new instance of `Person`\n// and every new instance of Person will trigger a rebuild in _every_ widget reading this value.\nChangeNotifierProvider.value(\n  value: Person(), \n  child: ...\n)\n```\n\n\nSo again, value constructors are best used when you need to provide a specific value that is already created. Some use-case examples: \n \n- Perhaps you need to provide an instance of an object that already exists where it otherwise isn't available. \n- Maybe you have a reason to hide a provided class from certain widgets, but you want to expose a piece of the class. Suppose you have a `Person` object provided to a big chunk of your widget tree, and you further on down the tree you want to expose the persons name (as a String), but none of their other properties.\n\nRegardless of your reasoning, this is what using a value constructor looks like:\n\n```dart\nclass PersonsNameLabel extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return Provider<String>.value(\n      value: Provider.of<Person>(context).name,\n      builder: (BuildContext context, Widget child) {\n        return Text(context.watch<String>());\n      },\n    );\n  }\n}\n```\n\n<div class=\"aside\">\nThere are a couple other examples in the <a href=\"https://pub.dev/packages/provider\">documentation</a> that use value constructors, but they're extremely specific and outside the scope of this tutorial.\n</div>\n\n\n### Live example of a .value constructor\n\n<iframe style=\"height:800px\" width=\"100%\" src=\"https://dartpad.dev/embed-flutter.html?theme=dark&run=true&split=60&id=db1df1bdb09a60f81308e589f60810d4\"></iframe>","created_at":"2020-07-25T15:09:44.011Z","id":110,"slug":"using-value-constructors","title":"Using .value constructors","tutorial":11,"updated_at":"2020-08-05T19:36:11.877Z"},{"author":1,"content":"As of version 4.1.0 of `Provider`, there are some tasty updates to reduce the boiler plate needed to use `Selector` and `Consumer`. (This is impressive, because Provider was already reducing a ton of InheritedWidget boiler plate.)\n\nBefore examples, it's important to understand the recent Dart changes that made this possible.  \n\n### Dart extension methods\n\nDart added `extension` methods to the language, which allows you to add properties and methods to classes from _other packages_. Which rules. Here's a quick example:\n\n```dart\n// extensions can be added to all classes, including enums!\nenum Connectivity {\n  connected, disconnected, searching\n}\n\nextension on Connectivity {\n  String humanize() => this.toString().split(\".\").last;\n}\n\nvoid main() {\n  print(Connectivity.connected.humanize());\n}\n```   \n\nThat's a pretty basic example, but you can extend anything. You can add a doubler method to ints:\n\n```dart\nextension on int {\n  int double() => this * 2;\n}\n```\n\nAnd so on.\n\n### Provider extends BuildContext \n\nProvider includes extension methods on Flutter's built in `BuildContext`. If you aren't familiar, build context is an object that holds reference to the widgets own place in the tree. It can then look up the tree to its ancestors, which is what makes [InheritedWidgets](https://ericwindmill.com/articles/inherited_widget/) possible, among many other things. \n\nThis why in Provider, you will see this line of code: `Provider.of<String>(context);`. This \"of\" method is using Flutter to look up the tree and find a `Provider` widget with the sub-type of `String`. (This isn't unique to provider, you will see it in many libraries, as well in Flutter functionality itself.) This is possible because `Provider` objects are implementations of widgets, so they have all the features of widgets you'd expect.\n\nAnyways, now that extensions are available, we can short-cut the process used to make `of` methods, and just add methods directly to build context. Which brings us to the better way to consumer providers:\n\n- `BuildContext.read`\n- `BuildContext.select`\n- `BuildContext.watch`\n\nEach of these simplifies a different process that previously a bit more verbose:\n\n`BuildContext.read<Person>()` replaces `Provider.of<Person>(context, listen: false)`.  In this case, it will find the `Person` object and then return it.\n\n`BuildContext.watch<Person>()` replaces `Provider.of<Person>(context)`. While this may seem hardly different, consider that you not do not need to use a Consumer at all. You can remove entire widgets from the tree! `watch` is used to 'listen' to a value from a  `ChangeNotifierProvider`, `FutureProvider` or `StreamProvider`.\n\nFinally, `BuildContext.select<Person>` is probably the most useful. It completely removes the need to use a `Selector`, as you can just use the value you would be selecting directly. I considered `Selector` the most cumbersome widget in the package to use, and to grok. But, it's all changed.\n\nTIRED: Using selector\n```dart\nWidget build(BuildContext context) {\n  return Selector<Person, String>(\n    selector: (context, p) => p.name,\n    builder: (context, name, child) {\n      return Text(name);\n    },\n  ),\n}\n``` \n\nWIRED: Using context.select: \n```dart\nWidget build(BuildContext context) {\n  final name = context.select((Person p) => p.name);\n  return Text(name);\n}\n```\n\nAnd, you still get the same benefits of the `Selector` widget. It will only rebuild the `Text` widget if the persons name is changed, and won't rebuild if any other property on the person object changes. Noice.\n\n### Live example:\n\n<iframe style=\"height:800px\" width=\"100%\" src=\"https://dartpad.dev/embed-flutter.html?theme=dark&run=true&split=60&id=2370deee8e452192c1a310fcac3b0aa2\"></iframe>\n\nNB: If you remember from an earlier lesson, `Provider` considers it an error to fetch an object or value that will never change, which we solved by using `listen: false`. Because `read` is a shortcut to this same functionality, `read` is valuable to do things like handle clicks (but not much else). It is considered an error to use `read` to get a value that a widget needs to paint.\n\n### Additional Reading:\n\n- [Using InheritedWidgets Effectively](https://ericwindmill.com/articles/inherited_widget/)\n- [Provider Change Log (look for 4.1.0)](https://pub.dev/packages/provider#-changelog-tab-)","created_at":"2020-07-25T15:07:23.488Z","id":107,"slug":"using-context-extensions-for-more-control","title":"Using context extensions for more control","tutorial":11,"updated_at":"2020-08-05T19:36:11.877Z"},{"author":1,"content":"In the last lesson, we looked at `Consumer`. Before we move back to types of providers, we should look at `Selector`. Selector is similar to consumer, but provides some fine control over when a widgets `build` method is called. In a nutshell, `selector` is a consumer that allows you to define exactly which properties from a model you care about.\n\nFor example, suppose you're working with a `User` class that has 25 properties on it. You don't need to rebuild, or even pass in, a text widget that displays a user name when you update their phone numbers. Selector used for just that.\n\nBecause `Selector` is so similar to `Consumer`, we should just jump into a code example.  \n\n<iframe style=\"height:800px\" src=\"https://dartpad.dev/embed-flutter.html?theme=dark&run=true&split=60&id=2c3dd865bf286490fff5412c052dfd46\"></iframe>\n\nIn my opinion, consumer is probably just fine for most use cases, unless you have an app that's so large that each build is a big deal. That said, this is all moot, because towards the end of this tutorial we will see even better ways to \"consume\" your models.\n","created_at":"2020-07-25T15:04:30.616Z","id":103,"slug":"finer-build-control-with-selector","title":"Finer build control with Selector","tutorial":11,"updated_at":"2020-08-05T19:36:11.877Z"}]},"strapiTableOfContents":{"contents":"{\n  \"Dart\": {\n    \"Getting Started with Dart\": [\n      \"About Dart\",\n      \"Install Dart on your machine\",\n      \"Dartpad\",\n      \"Text Editors: Intellij and VSCode\",\n      \"Resources: Documentation and Pub.dev\",\n      \"Hello World\",\n      \"The main function\",\n      \"Print to the console\"\n    ],\n    \"Dart Fundamentals\": [\n      \"Values and variables\",\n      \"Comments\",\n      \"const and final variables\",\n      \"Arithmetic and Comparison Operators\",\n      \"Assignment Operators\",\n      \"Logical Operators\",\n      \"Null Aware Operators\",\n      \"Type Test Operators\",\n      \"Bitwise and Shift Operators\",\n      \"Control Flow: if, else, else if\",\n      \"Switch statements and case\",\n      \"Ternary Conditional operator\",\n      \"Loops: for and while\",\n      \"Anatomy of Dart Functions\",\n      \"Arrow functions\",\n      \"Function arguments: default, optional, named\",\n      \"Lexical Scope\",\n      \"Cascade notation\"\n    ],\n    \"Data Types\": [\n      \"Intro to Dart's Type System\",\n      \"Numbers\",\n      \"Strings\",\n      \"Booleans\",\n      \"dynamic\",\n      \"lists\",\n      \"sets\",\n      \"maps\"\n    ],\n    \"Object-Oriented Programming\": [\n      \"Intro to OOP\",\n      \"Classes\",\n      \"Constructors\",\n      \"Properties and methods\",\n      \"Methods: static, private, etc\",\n      \"Getters and setters\",\n      \"Extending classes (inheritance)\",\n      \"Initializer lists and final properties\",\n      \"Factory methods\",\n      \"Singletons\",\n      \"Abstract classes (and interfaces)\",\n      \"Mixins\",\n      \"Extension methods\"\n    ],\n    \"Iterables, Iterators, and Collections\": [\n      \"What are collections (and iterables)?\",\n      \"Looping: for-in and forEach\",\n      \"Reading elements pt 1: first, last\",\n      \"Adding elements: add and insert (all)\",\n      \"Checking for elements: contains, indexOf, any, every\",\n      \"Removing elements: remove, clear, removeWhere\",\n      \"Filtering elements: where, takeWhile, and skipWhile\",\n      \"Changing elements: map and expand\",\n      \"Deriving values from elements: fold, reduce, join\",\n      \"Type casting collections: cast, as, retype, toSet, toList\",\n      \"Iterators: understanding and creating your own\",\n      \"Iterable-like methods on maps (and putIfAbsent)\"\n    ]\n  },\n  \"Flutter\": {\n    \"Getting started with Flutter\": [\n      \"About Flutter\",\n      \"IDEs and resources\"\n    ],\n    \"Widgets\": [\n      \"Intro to Widgets\",\n      \"Widget types: Stateful and Stateless\",\n      \"StatefulWidget lifecycle\",\n      \"The Widget tree\",\n      \"BuildContext\",\n      \"Inherited Widgets\",\n      \"Thinking in widgets\"\n    ],\n    \"Intro Flutter App\": [\n      \"Intro and Setup\",\n      \"Data Model and HTTP\",\n      \"Build a custom widget\",\n      \"ListView and builder pattern\",\n      \"Gradient Backgrounds\",\n      \"Routing: Add a detail page\",\n      \"Routing 2: Add a form page\",\n      \"User Input\",\n      \"Sliders and Buttons\",\n      \"Snackbars and Dialogs\",\n      \"Built-in Animation: AnimatedCrossFade\",\n      \"Built-in Animation: Hero transition\"\n    ],\n    \"Custom Animation: Progress Indicator\": [\n      \"Intro and Overview\",\n      \"Build the example app boiler-plate\",\n      \"Custom Widget: Peg\",\n      \"Tween and AnimationController classes\",\n      \"Tween by example\",\n      \"Using Tweens and Intervals\",\n      \"Wrap the Pegs in AnimatedWidgets\",\n      \"Bring it all together\"\n    ],\n    \"State Management: Blocs without Libraries\": [\n      \"What are blocs?\",\n      \"Calendar App introduction\",\n      \"Create bloc one\",\n      \"Create a bloc provider\",\n      \"Using StreamBuilders with blocs\",\n      \"Create bloc two: Add/Edit Tasks\",\n      \"Consume the second bloc's streams\",\n      \"Complete source code\"\n    ],\n    \"State Management: Provider\": [\n      \"What is Provider?\",\n      \"The most basic example using Provider\",\n      \"ChangeNotifierProvider\",\n      \"Rebuilding widgets with Consumer\",\n      \"Finer build control with Selector\",\n      \"Future Provider\",\n      \"MultiProvider micro lesson\",\n      \"Stream Provider\",\n      \"Using context extensions for more control\",\n      \"ProxyProvider\",\n      \"Using .value constructors\",\n      \"The final example (A shopping cart app)\",\n      \"For the curious: How is provider implemented\"\n    ],\n    \"Handling Data with Brick: Offline First with Rest\": [\n      \"About Brick and setup\",\n      \"Adding a Repository\",\n      \"Adding a Model\",\n      \"Generating Code\",\n      \"Rendering Models\",\n      \"Adding an Association\"\n    ]\n  }\n}"}},"pageContext":{"slug":"future-provider","tutorialTitle":"State Management: Provider","previous":{"author":1,"content":"\n[`StreamProvider`](https://pub.dev/documentation/provider/latest/provider/StreamProvider-class.html) provides, well, Streamed values. Like FutureProvider, provided values will be auto-magically passed the new values of the provided value as they come in. The major difference is that the values will trigger a re-build as many times as it needs to. \n\n<div class=\"aside\">\n    If you need a refresher on Streams, I recommend you  <a href=\"https://ericwindmill.com/articles/async_dart_flutter/\">check out my code-cartoon of Dart Streams</a>, or find a whole chapter about Streams in my book <a href=\"bit.ly/flutterinaction\">Flutter in Action</a>. Streams can be hard to grasp (and implement) if you aren't familiar, but they're wildly useful and popular in the Flutter ecosystem.\n</div>\n\n\n`StreamProviders` work so similarly to `FutureProvider`, that we should just jump straight into code. First, setting up the stream:\n\n```dart\nclass Person {\n  Person({this.name, this.initialAge});\n\n  final String name;\n  final int initialAge;\n\n  // A StreamProvider's only requirement is that, well,\n  // you give it a stream value.\n  // This [generator] function will _yield_ a new number every second.\n  Stream<String> get age async* {\n    var i = initialAge;\n    while (i < 85) {\n      await Future.delayed(Duration(seconds: 1), () {\n        i++;\n      });\n      yield i.toString();\n    }\n  }\n}\n```\n\n## Live Example\n\n<iframe height=\"800px\" width=\"100%\" src=\"https://dartpad.dev/embed-flutter.html?theme=dark&run=true&split=60&id=59c25f7f9b44c740b033ed1bc36101cf\"></iframe>\n\n","created_at":"2020-07-25T15:06:42.585Z","id":106,"slug":"stream-provider","title":"Stream Provider","tutorial":11,"updated_at":"2020-08-06T16:20:15.289Z"},"next":{"author":1,"content":"\nIn the `FutureProvider` lesson, you may have noticed something ugly.\n\n```dart\nvoid main() {\n  runApp(\n    Provider<Person>(\n      create: (_) => Person(name: 'Yohan', age: 25),\n      child: FutureProvider<String>(\n        create: (context) => Home().fetchAddress,\n        initialData: \"fetching address...\", \n        child: MyApp(),\n      ),\n    ),\n  );\n}\n```\n\nThere are two providers, one nested inside the over. You can imagine this getting quickly out of hand:\n\n```dart\nvoid main() {\n  runApp(\n    // You can wrap multiple providers \n    Provider<Person>(\n      create: (_) => Person(name: 'Yohan', age: 25),\n      child: FutureProvider<String>(\n        create: (context) => Home().fetchAddress,\n        initialData: \"fetching address...\", \n        child: StreamProvider<Connectivity>(\n          create: (context) => Session.connectivity(),\n          child: ChangeNotifierProvider<AuthState>(\n            create: (context) => Session.authState(),\n            child: MyApp(),\n         ),\n        ),\n      ),\n    ),\n  );\n}\n```\n\nThis isn't super readable. Provider includes a fix for this: [MultiProvider](https://pub.dev/documentation/provider/latest/provider/MultiProvider-class.html).\n\n`MultiProvider` let's you pass in a list of providers without nesting anything,\n\n```dart\nvoid main() {\n  runApp(\n    // You can wrap multiple providers \n    MultiProvider(\n      providers: [\n        Provicer<Person>(create: (_) => Person(name: 'Yohan', age: 25)),\n        FutureProvider<String>(create: (context) => Home().fetchAddress),\n      ],\n      child: MyApp(),\n    ),\n  );\n}\n```\n\nThis widget just makes code more terse and readable. Which is always nice.\n\n<div class=\"aside\">\nIf you really want to be impressed by the creator of Provider, <a href=\"https://github.com/rrousselGit\">Remi</a>, check out his package called <a href=\"https://pub.dev/packages/nested\">nested</a>, which provides widgets that can take a list of children and nest them. This is what `MultiProvider` is built on top of.  \n</div>","created_at":"2020-07-25T15:06:10.841Z","id":105,"slug":"multi-provider-micro-lesson","title":"MultiProvider micro lesson","tutorial":11,"updated_at":"2020-08-05T19:36:11.877Z"}}},"staticQueryHashes":["2185715291","3564968493","63159454"]}