call autoDisposefamily AsyncNotifierProviderBuilder"AsyncNotifierProviderFamilyBuilder'AutoDisposeAsyncNotifierProviderBuilder-AutoDisposeAsyncNotifierProviderFamilyBuilderNotifierProviderBuilderNotifierProviderFamilyBuilder"AutoDisposeNotifierProviderBuilder(AutoDisposeNotifierProviderFamilyBuilderStreamNotifierProviderBuilder#StreamNotifierProviderFamilyBuilder(AutoDisposeStreamNotifierProviderBuilder.AutoDisposeStreamNotifierProviderFamilyBuilderStateProviderBuilderStateProviderFamilyBuilderStateNotifierProviderBuilder"StateNotifierProviderFamilyBuilderProviderBuilderProviderFamilyBuilderFutureProviderBuilderFutureProviderFamilyBuilderStreamProviderBuilderStreamProviderFamilyBuilderAutoDisposeStateProviderBuilder%AutoDisposeStateProviderFamilyBuilder'AutoDisposeStateNotifierProviderBuilder-AutoDisposeStateNotifierProviderFamilyBuilderAutoDisposeProviderBuilder AutoDisposeProviderFamilyBuilder AutoDisposeFutureProviderBuilder&AutoDisposeFutureProviderFamilyBuilder AutoDisposeStreamProviderBuilder&AutoDisposeStreamProviderFamilyBuilder@AsyncNotifierProvider AsyncNotifierStringIterableProviderOrFamilyname dependenciesAsyncNotifierProviderFamilyFamilyAsyncNotifier AutoDisposeAsyncNotifierProviderAutoDisposeAsyncNotifier&AutoDisposeAsyncNotifierProviderFamilyAutoDisposeFamilyAsyncNotifierNotifierProviderNotifierNotifierProviderFamilyFamilyNotifierAutoDisposeNotifierProviderAutoDisposeNotifier!AutoDisposeNotifierProviderFamilyAutoDisposeFamilyNotifierStreamNotifierProviderStreamNotifierStreamNotifierProviderFamilyFamilyStreamNotifier!AutoDisposeStreamNotifierProviderAutoDisposeStreamNotifier'AutoDisposeStreamNotifierProviderFamilyAutoDisposeFamilyStreamNotifier StateProviderStreamProviderCreateStateProviderRefFutureProviderStateProviderFamily FamilyCreateStateNotifierProvider StateNotifierStateNotifierProviderRefStateNotifierProviderFamilyProvider ProviderRefProviderFamilyFutureOrFutureProviderRefFutureProviderFamilyStreamStreamProviderRefStreamProviderFamilyAutoDisposeStateProviderAutoDisposeStateProviderRefAutoDisposeStateProviderFamily AutoDisposeStateNotifierProvider#AutoDisposeStateNotifierProviderRef&AutoDisposeStateNotifierProviderFamilyAutoDisposeProviderAutoDisposeProviderRefAutoDisposeProviderFamilyAutoDisposeFutureProviderAutoDisposeFutureProviderRefAutoDisposeFutureProviderFamilyAutoDisposeStreamProviderAutoDisposeStreamProviderRefAutoDisposeStreamProviderFamilyá¡&ã'¨m\ÀÙå˜1@„�³ dart:async�È*package:state_notifier/state_notifier.dart�þinternals.dartÀS>À�¥„9*-€–€™€Ç���O�±�²�Ç�ü�ý‚‚‚=‚b‚Š‚²‚³‚ׂýƒ0ƒSƒeƒ“ƒšƒÊƒØƒê„ „„„„<„x„´„¸„¹„Ø… …A…E…G…H…t…Ÿ…Í…û…ü††L†�†²†Ä†ò†ù‡4‡B‡T‡v‡}‡�‡‚‡¦‡èˆ*ˆ.ˆ0ˆ1ˆbˆ’ˆÅˆøˆù‰‰N‰Œ‰¯‰Á‰ï‰öŠ1Š?ŠQŠsŠzŠ~ŠŠžŠÛ‹‹!‹#‹$‹[‹‘‹ÊŒŒŒ#Œ_Œ­ŒÐŒâ���]�k�}�Ÿ�¦�ª�¬�­�Î�4Ž5ŽYŽ~Ž´Ž×Žé���M�[�m���–�š�›�¿�ö�-�1�2�Q�~�°�´�¶�·�Þ‘‘-‘V‘W‘v‘¦‘ì’’!’O’V’�’ž’°’Ò’Ù’Ý’Þ““?“|“€“‚“ƒ“¯“Ú””6”7”[”‹”̔/•6•p•~•�•²•¹•½•¾•Ý––R–V–X–Y–‹–¼–ð—$—%—D——Зó˜˜3˜:˜˜�˜Ÿ˜Á˜È˜Ì˜Î˜Ï˜ö™™E™n™o™“™º™îšš#šQšXš‰š—š©šËšÒšÖš×šû›8›u›y›z›™›Ìœœœ œ œ8œdœ“œÂœÃœâ��X�{���»�Â�þž žž@žGžKžLžpž³žöžúžüžýŸ/Ÿ`Ÿ”ŸÈŸÉŸí  ^ � “ Á È¡¡¡$¡F¡M¡Q¡R¡q¡¯¡ò¡ö¡ø¡ù¢1¢h¢¢¢Ü¢Ý¢ü£9£ˆ£«£½£ë£ò¤9¤G¤Y¤{¤‚¤†¤ˆ¤‰¤§¤Ä¤ä¥¥¥,¥{¥�¥Ÿ¥¥¥ð¦E¦‡¦Ô¦ñ§H§N§«§±¨¨A¨G¨—¨¨¨®¨¼¨þ©2©K©d©n©x©~©ÐªªQª’ª˜ªè«1«ƒ«‰«—«Ù¬¬7¬=¬‡¬·¬Ð¬é¬ó¬ý­­6­m­¢­´­â­é® ®®*®L®S®W®X®|®°®ä®è®é¯ ¯Z¯`¯¯¯Ò¯Ø°°°&°r° °Ä°ù±±*±6±<±K±Q±c±Ÿ±Ù±ß²²e²�²£²Á²Ë²×²Ý³%³+³;³�³Ð´´´´&´,´>´z´³´¹´üµFµŸµÕ¶ ¶¶-¶Z¶˜¶Ð¶Ý¶ç¶ó¶ù·S·Y·i·ä¸(¸x¸°¸¼¸È¸Î¸Ý¸ã¹1¹„¹Š¹Ö¹õ¹ûº º_º™º£º­º³» »»!»/»i»�»Ñ»Ù»ã»é¼¼F¼L¼Z¼”¼Î¼Ö¼à¼æ½7½„½À½Æ½Ô½ä¾¾f¾¯¾µ¾ð¾ø¿¿¿'¿-¿~¿¹¿¿À@À@jÀ@pÀ@vÀ@ÁÀ@üÀAÀAÀAnÀAzÀA†ÀAŒÀAÞÀAøÀAþÀB.ÀB4ÀB‡ÀB�ÀBáÀCÀCÀC*ÀCRÀC…ÀC²ÀC¸ÀCÍÀCõÀD2ÀDBÀDSÀD‹ÀD«ÀDÌÀDðÀE ÀEÀEÀEzÀEŸÀEÄÀEñÀEýÀFÀFÀFQÀFŠÀFÄÀFÊÀFñÀG;ÀGHÀGRÀG^ÀGdÀG›ÀG«ÀGÚÀGúÀHÀH>ÀHLÀHRÀHnÀHŒÀH’ÀH¦ÀHÜÀHæÀHìÀIIÀInÀI“ÀIÀÀIÌÀIÒÀIäÀJ ÀJYÀJ“ÀJ™ÀJÀÀK ÀKÀK!ÀK-ÀKBÀKlÀK›ÀKŸÀK¡ÀK¢ÀKÆÀKéÀLÀL5ÀL6ÀLUÀL‰ÀLÀÀMÀMÀM@ÀMGÀMsÀM�ÀM“ÀMµÀM¼ÀMÀÀMÁÀMåÀNÀNYÀN]ÀN_ÀN`ÀN†ÀN«ÀNÓÀNûÀNüÀO ÀOIÀOƒÀOºÀPÀPÀPDÀPKÀP~ÀPŒÀPžÀPÀÀPÇÀPËÀPÌÀPðÀQ,ÀQhÀQlÀQmÀQŒÀQ¾ÀQõÀQùÀQûÀQüÀR(ÀRSÀR�ÀR¯ÀR°ÀRÏÀSÀSBÀSyÀSÄÀSÖÀSèÀTÀTÀT[ÀTiÀT{ÀT�ÀT¤ÀT¨ÀT©ÀTÍÀUÀUQÀUUÀUWÀUXÀUqÀU‰ÀU¤ÀU¿ÀUÀÀUäÀVÀV:ÀVjÀV|ÀVªÀV±ÀVÍÀVÛÀVíÀWÀWÀWÀWÀW?ÀWnÀW�ÀW¡ÀW¢ÀWÁÀWæÀXÀXÀXÀXÀX6ÀXTÀXuÀX–ÀX—ÀX¶ÀXåÀYÀYWÀYiÀY—ÀYžÀYÅÀYÓÀYåÀZÀZÀZÀZÀZ7ÀZlÀZ¡ÀZ¥ÀZ§ÀZ¨ÀZÇÀZåÀ[À['À[(À[LÀ[qÀ[¨À[èÀ[úÀ\(À\/À\QÀ\_À\qÀ\“À\šÀ\žÀ\ŸÀ\ÃÀ\øÀ]-À]1À]2À]QÀ]|À]¬À]°À]²À]³À]ØÀ]üÀ^#À^JÀ^KÀ^jÀ^ŸÀ^ÖÀ_!À_3À_aÀ_hÀ_•À_£À_µÀ_×À_ÞÀ_âÀ_ãÀ`À`BÀ`}À`�À`ƒÀ`„À`£À`ÁÀ`âÀaÀaÀa(ÀaMÀa„ÀaÂÀaÔÀbÀb Àb+Àb9ÀbKÀbmÀbtÀbxÀbyÀb�ÀbÒÀcÀc Àc Àc+ÀcVÀc†ÀcŠÀcŒÀc�Àc²ÀcÖÀcýÀd$Àd%ÀdDÀdyÀd°ÀdùÀe Àe9Àe@ÀemÀe{Àe�Àe¯Àe¶ÀeºÀe»ÀeßÀfÀfUÀfYÀf[Àf\Àf…Àf­ÀfØÀgÀgÀg(ÀgWÀgŽÀgÎÀgàÀhÀhÀhAÀhOÀhaÀhƒÀhŠÀhŽÀh�Àh®ÀhãÀiÀi!Ài#Ài$ÀiSÀi�Ài²ÀiãÀiäÀjÀjBÀjyÀjÄÀjÖÀkÀk ÀkBÀkPÀkbÀk„Àk‹Àk�Àk‘Àk’ÀkÃÀkóÀl&ÀlYÀlZÀl~Àl²ÀlìÀm#ÀmnÀm€Àm’ÀmÀÀmÇÀnÀnÀn%ÀnGÀnNÀnRÀnSÀnrÀn¯ÀnñÀnõÀn÷ÀnøÀo/ÀoeÀožÀo×ÀoØÀo÷Àp6ÀpuÀp¬ÀpýÀqÀq Àq2Àq`ÀqgÀq°Àq¾ÀqÐÀqòÀqùÀqýÀqÿÀrÀr$ÀrGÀrmÀr“Àr”Àr¸ÀrâÀsÀsTÀsfÀs”Às›ÀsÂÀsÐÀsâÀtÀt ÀtÀtÀt/Àt_Àt”Àt˜ÀtšÀt›ÀtÅÀtîÀuÀuFÀuGÀufÀu Àu×ÀvÀv/Àv]ÀvdÀv–Àv¤Àv¶ÀvØÀvßÀvãÀvåÀvæÀwÀw9ÀweÀw‘Àw’Àw¶ÀwæÀxÀxhÀxzÀx¨Àx¯ÀxÜÀxêÀxüÀyÀy%Ày)Ày*ÀyIÀyÀyºÀy¾ÀyÀÀyÁÀyñÀz ÀzRÀz„Àz…Àz¤ÀzäÀ{À{gÀ{yÀ{‹À{¹À{ÀÀ{øÀ|À|À|:À|AÀ|EÀ|GÀ|HÀ|rÀ|›À|ÇÀ|óÀ|ôÀ}À}HÀ}À}ÈÀ}ÚÀ~À~À~<À~JÀ~\À~~À~…À~‰À~ŠÀ~©À~ßÀÀÀ À!ÀQÀ€À²ÀäÀåÀ€À€DÀ€{À€ÅÀ€×À€éÀ�À�À�VÀ�dÀ�vÀ�˜À�ŸÀ�£À�¥�²�Ç�ý ‚’‚®‚d‚dM%/// Builds a [AsyncNotifierProvider].„„€�„j!/// {@macro riverpod.autoDispose}„»„»€‰…/// {@macro riverpod.family}ƒƒ"ƒƒ,ƒ,ƒ,ƒ4ƒ4ƒIƒWƒW ƒ_ƒiƒi(ƒ…‚µ‚µ�aƒ!/// {@macro riverpod.autoDispose}‚‚ƒ/‚C%/// Builds a [AsyncNotifierProvider].…Õ…÷…¡…¡Y+/// Builds a [AsyncNotifierProviderFamily].‡„‡„€©‡Ú!/// {@macro riverpod.autoDispose}†W†W-†W†††††††‰†‰†‰†“†“†¨†¶†¶ †¾†È†È(†ä…þ…þ�‚†R/// {@macro riverpod.family}…H…H‚ç…z+/// Builds a [AsyncNotifierProviderFamily].ˆÍˆôˆ”ˆ”c0/// Builds a [AutoDisposeAsyncNotifierProvider].Š�Š�€ŸŠÒ/// {@macro riverpod.family}‰Y‰Y-‰Y‰ˆ‰ˆ‰ˆ‰�‰�‰¥‰³‰³ ‰»‰Å‰Å(‰áˆûˆû�‚‰T!/// {@macro riverpod.autoDispose}ˆ1ˆ1‚ñˆh0/// Builds a [AutoDisposeAsyncNotifierProvider].‹Ò‹ÿ‹“‹“o6/// Builds a [AutoDisposeAsyncNotifierProviderFamily].ŒjŒj8ŒjŒ¤Œ¤Œ¤Œ§Œ§Œ§Œ±Œ±ŒÆŒÔŒÔ ŒÜŒæŒæ(�ŒŒ�£Œe/// {@macro riverpod.family}‹$‹$‚‡‹a6/// Builds a [AutoDisposeAsyncNotifierProviderFamily].ŽŽ0�ð�ðC /// Builds a [NotifierProvider].����€“�è!/// {@macro riverpod.autoDispose}�4�4�u/// {@macro riverpod.family}މމ!މެެެޏޏŽÍŽÛŽÛ ŽãŽíŽí(� Ž7Ž7�bŽ„!/// {@macro riverpod.autoDispose}�­�­ƒ�Ô /// Builds a [NotifierProvider].‘5‘R‘‘O&/// Builds a [NotifierProviderFamily].’à’à€Ÿ“1!/// {@macro riverpod.autoDispose}‘±‘±,‘±‘ß‘ß‘ß‘æ‘æ‘æ‘ð‘ð’’’ ’’%’%(’A‘Y‘Y�ƒ‘¬/// {@macro riverpod.family}�·�·‚Ê�ä&/// Builds a [NotifierProviderFamily].””2“Ü“ÜY+/// Builds a [AutoDisposeNotifierProvider].•À•À€•– /// {@macro riverpod.family}”–”–,”–”ĔĔĔДДå”ó”ó ”û••(•!”9”9�ƒ”‘!/// {@macro riverpod.autoDispose}“ƒ“ƒ‚Ô“µ+/// Builds a [AutoDisposeNotifierProvider].–ø— –¾–¾e1/// Builds a [AutoDisposeNotifierProviderFamily].—Š—Š7—Š—Ã—Ã—×ʗÊ—Ê—Ô—Ô—é—÷—÷ —ÿ˜ ˜ (˜%—'—'�¤—…/// {@macro riverpod.family}–Y–Y‚t–‘1/// Builds a [AutoDisposeNotifierProviderFamily].™M™j™™O&/// Builds a [StreamNotifierProvider].šÙšÙ€Ÿ›*!/// {@macro riverpod.autoDispose}›|›|€‹›Ã/// {@macro riverpod.family}™Å™Å#™Å™ê™ê™ê™ò™òššš šš'š'(šC™q™q�d™À!/// {@macro riverpod.autoDispose}˜Ï˜Ïƒ:˜ü&/// Builds a [StreamNotifierProvider].œ›œ¾œfœf[,/// Builds a [StreamNotifierProviderFamily].žNžN€«ž¥!/// {@macro riverpod.autoDispose}��.��O�O�O�R�R�R�\�\�q�� �‡�‘�‘(�­œÅœÅ�…�/// {@macro riverpod.family}œ œ ‚ðœ>,/// Builds a [StreamNotifierProviderFamily].ŸœŸÄŸbŸbe1/// Builds a [AutoDisposeStreamNotifierProvider].¡T¡T€¡¡¦/// {@macro riverpod.family} * *. * Z Z Z b b w … …  � — —( ³ŸËŸË�… %!/// {@macro riverpod.autoDispose}žýžý‚úŸ51/// Builds a [AutoDisposeStreamNotifierProvider].¢ª¢Ø¢j¢jq7/// Builds a [AutoDisposeStreamNotifierProviderFamily].£D£D9£D££££‚£‚£‚£Œ£Œ£¡£¯£¯ £·£Á£Á(£Ý¢ß¢ß�¦£?/// {@macro riverpod.family}¡ù¡ù‚Ž¢77/// Builds a [AutoDisposeStreamNotifierProviderFamily].¤ì¥¤Æ¤Æ=/// Builds a [StateProvider].®Z®Z€�®¢!/// {@macro riverpod.autoDispose}®ë®ëœ³ÀKcš¹/// {@template riverpod.family} /// A group of providers that builds their value from an external parameter. /// /// Families can be useful to connect a provider with values that it doesn't /// have access to. For example: /// /// - Allowing a "title provider" access the `Locale` /// /// ```dart /// final titleFamily = Provider.family((ref, locale) { /// if (locale == const Locale('en')) { /// return 'English title'; /// } else if (locale == const Locale('fr')) { /// return 'Titre Français'; /// } /// }); /// /// // ... /// /// @override /// Widget build(BuildContext context, WidgetRef ref) { /// final locale = Localizations.localeOf(context); /// /// // Obtains the title based on the current Locale. /// // Will automatically update the title when the Locale changes. /// final title = ref.watch(titleFamily(locale)); /// /// return Text(title); /// } /// ``` /// /// - Have a "user provider" that receives the user ID as a parameter /// /// ```dart /// final userFamily = FutureProvider.family((ref, userId) async { /// final userRepository = ref.read(userRepositoryProvider); /// return await userRepository.fetch(userId); /// }); /// /// // ... /// /// @override /// Widget build(BuildContext context, WidgetRef ref) { /// int userId; // Read the user ID from somewhere /// /// // Read and potentially fetch the user with id `userId`. /// // When `userId` changes, this will automatically update the UI /// // Similarly, if two widgets tries to read `userFamily` with the same `userId` /// // then the user will be fetched only once. /// final user = ref.watch(userFamily(userId)); /// /// return user.when( /// data: (user) => Text(user.name), /// loading: () => const CircularProgressIndicator(), /// error: (err, stack) => const Text('error'), /// ); /// } /// ``` /// /// - Connect a provider with another provider without having a direct reference on it. /// /// ```dart /// final repositoryProvider = Provider.family>((ref, configurationsProvider) { /// // Read a provider without knowing what that provider is. /// final configurations = await ref.read(configurationsProvider.future); /// return Repository(host: configurations.host); /// }); /// ``` /// /// ## Usage /// /// The way families works is by adding an extra parameter to the provider. /// This parameter can then be freely used in our provider to create some state. /// /// For example, we could combine `family` with [FutureProvider] to fetch /// a `Message` from its ID: /// /// ```dart /// final messagesFamily = FutureProvider.family((ref, id) async { /// return dio.get('http://my_api.dev/messages/$id'); /// }); /// ``` /// /// Then, when using our `messagesFamily` provider, the syntax is slightly modified. /// The usual: /// /// ```dart /// Widget build(BuildContext context, WidgetRef ref) { /// // Error – messagesFamily is not a provider /// final response = ref.watch(messagesFamily); /// } /// ``` /// /// will not work anymore. /// Instead, we need to pass a parameter to `messagesFamily`: /// /// ```dart /// Widget build(BuildContext context, WidgetRef ref) { /// final response = ref.watch(messagesFamily('id')); /// } /// ``` /// /// **NOTE**: It is totally possible to use a family with different parameters /// simultaneously. For example, we could use a `titleFamily` to read both /// the french and english translations at the same time: /// /// ```dart /// @override /// Widget build(BuildContext context, WidgetRef ref) { /// final frenchTitle = ref.watch(titleFamily(const Locale('fr'))); /// final englishTitle = ref.watch(titleFamily(const Locale('en'))); /// /// return Text('fr: $frenchTitle en: $englishTitle'); /// } /// ``` /// /// # Parameter restrictions /// /// For families to work correctly, it is critical for the parameter passed to /// a provider to have a consistent `hashCode` and `==`. /// /// Ideally the parameter should either be a primitive (bool/int/double/String), /// a constant (providers), or an immutable object that override `==` and `hashCode`. /// /// /// - **PREFER** using `family` in combination with `autoDispose` if the /// parameter passed to providers is a complex object: /// /// ```dart /// final example = Provider.autoDispose.family((ref, param) { /// }); /// ``` /// /// This ensures that there is no memory leak if the parameter changed and is /// never used again. /// /// # Passing multiple parameters to a family /// /// Families have no built-in support for passing multiple values to a provider. /// /// On the other hand, that value could be _anything_ (as long as it matches with /// the restrictions mentioned previously). /// /// This includes: /// - A tuple (using `package:tuple`) /// - Objects generated with Freezed/built_value /// - Objects based on `package:equatable` /// /// This includes: /// - A tuple (using `package:tuple`) /// - Objects generated with Freezed/built_value, such as: /// ```dart /// @freezed /// abstract class MyParameter with _$MyParameter { /// factory MyParameter({ /// required int userId, /// required Locale locale, /// }) = _MyParameter; /// } /// /// final exampleProvider = Provider.family((ref, myParameter) { /// print(myParameter.userId); /// print(myParameter.locale); /// // Do something with userId/locale /// }); /// /// @override /// Widget build(BuildContext context, WidgetRef ref) { /// int userId; // Read the user ID from somewhere /// final locale = Localizations.localeOf(context); /// /// final something = ref.watch( /// exampleProvider(MyParameter(userId: userId, locale: locale)), /// ); /// } /// ``` /// /// - Objects based on `package:equatable`, such as: /// ```dart /// class MyParameter extends Equatable { /// factory MyParameter({ /// required this.userId, /// requires this.locale, /// }); /// /// final int userId; /// final Local locale; /// /// @override /// List get props => [userId, locale]; /// } /// /// final exampleProvider = Provider.family((ref, myParameter) { /// print(myParameter.userId); /// print(myParameter.locale); /// // Do something with userId/locale /// }); /// /// @override /// Widget build(BuildContext context, WidgetRef ref) { /// int userId; // Read the user ID from somewhere /// final locale = Localizations.localeOf(context); /// /// final something = ref.watch( /// exampleProvider(MyParameter(userId: userId, locale: locale)), /// ); /// } /// ``` /// {@endtemplate}­.­.­.­q­q-­˜­¦­¦ ­®­¸­¸(­Ô¥¥‰O­)‡ª/// {@template riverpod.autoDispose} /// Marks the provider as automatically disposed when no longer listened to. /// /// Some typical use-cases: /// /// - Combined with [StreamProvider], this can be used as a mean to keep /// the connection with Firebase alive only when truly needed (to reduce costs). /// - Automatically reset a form state when leaving the screen. /// - Automatically retry HTTP requests that failed when the user exit and /// re-enter the screen. /// - Cancel HTTP requests if the user leaves a screen before the request completed. /// /// Marking a provider with `autoDispose` also adds an extra method on `ref`: `keepAlive`. /// /// The `keepAlive` function is used to tell Riverpod that the state of the provider /// should be preserved even if no longer listened to. /// /// A use-case would be to set this flag to `true` after an HTTP request have /// completed: /// /// ```dart /// final myProvider = FutureProvider.autoDispose((ref) async { /// final response = await httpClient.get(...); /// ref.keepAlive(); /// return response; /// }); /// ``` /// /// This way, if the request failed and the UI leaves the screen then re-enters /// it, then the request will be performed again. /// But if the request completed successfully, the state will be preserved /// and re-entering the screen will not trigger a new request. /// /// It can be combined with `ref.onDispose` for more advanced behaviors, such /// as cancelling pending HTTP requests when the user leaves a screen. /// For example, modifying our previous snippet and using `dio`, we would have: /// /// ```diff /// final myProvider = FutureProvider.autoDispose((ref) async { /// + final cancelToken = CancelToken(); /// + ref.onDispose(() => cancelToken.cancel()); /// /// + final response = await dio.get('path', cancelToken: cancelToken); /// - final response = await dio.get('path'); /// ref.keepAlive(); /// return response; /// }); /// ``` /// {@endtemplate}¤‰¤‰§¤­/// Builds a [StateProvider].ÀLÀL1ÀKëÀKëI#/// Builds a [StateProviderFamily].ÀMÃÀMÀ™ÀN!/// {@macro riverpod.autoDispose}ÀL|ÀL|ÀL|ÀLƒÀLƒÀLƒÀLÄÀLÄ8ÀLöÀMÀM ÀM ÀMÀM(ÀM2ÀL8ÀL8�‡ÀLw/// {@macro riverpod.family}ÀK¢ÀK¢‚¼ÀKÌ#/// Builds a [StateProviderFamily].ÀNÛÀN÷ÀN­ÀN­M%/// Builds a [StateNotifierProvider].ÀPÎÀP΀�ÀQ!/// {@macro riverpod.autoDispose}ÀQoÀQo€‰ÀQµ/// {@macro riverpod.family}ÀOTÀOT%ÀOTÀO{ÀO{ÀO{ÀO¾ÀO¾BÀOúÀPÀP ÀPÀPÀP(ÀP6ÀNþÀNþ�ÌÀOO!/// {@macro riverpod.autoDispose}ÀN`ÀN`ƒšÀNŒ%/// Builds a [StateNotifierProvider].ÀR‰ÀR«ÀRUÀRUY+/// Builds a [StateNotifierProviderFamily].ÀT«ÀT«€©ÀU!/// {@macro riverpod.autoDispose}ÀSÀS%ÀSÀS5ÀS5ÀS5ÀS<ÀS<ÀS<ÀS}ÀS}UÀSÌÀSÚÀSÚ ÀSâÀSìÀSì(ÀTÀR²ÀR²�õÀS /// {@macro riverpod.family}ÀQüÀQüƒZÀR.+/// Builds a [StateNotifierProviderFamily].ÀU¬ÀU»ÀU‹ÀU‹3/// Builds a [Provider].ÀWÀW€ƒÀW`!/// {@macro riverpod.autoDispose}ÀW¤ÀW¤oÀWÝ/// {@macro riverpod.family}ÀUûÀUûÀUûÀV>ÀV>(ÀV`ÀVnÀVn ÀVvÀV€ÀV€(ÀVœÀUÂÀUÂ�WÀUö!/// {@macro riverpod.autoDispose}ÀUXÀUX‚½ÀUw/// Builds a [Provider].ÀX}ÀX’ÀXVÀXV?/// Builds a [ProviderFamily].ÀZÀZ€�ÀZ^!/// {@macro riverpod.autoDispose}ÀXØÀXØÀXØÀXßÀXßÀXßÀY ÀY 3ÀYMÀY[ÀY[ ÀYcÀYmÀYm(ÀY‰ÀX™ÀX™�xÀXÓ/// {@macro riverpod.family}ÀXÀX‚�ÀX</// Builds a [ProviderFamily].À[À[#ÀZçÀZç?/// Builds a [FutureProvider].À\¡À\¡€�À\ê!/// {@macro riverpod.autoDispose}À]4À]4{À]s/// {@macro riverpod.family}À[iÀ[iÀ[iÀ[¬À[¬8À[ÞÀ[ìÀ[ì À[ôÀ[þÀ[þ(À\À[*À[*�sÀ[d!/// {@macro riverpod.autoDispose}ÀZ¨ÀZ¨ƒ ÀZÍ/// Builds a [FutureProvider].À^+À^FÀ]þÀ]þK$/// Builds a [FutureProviderFamily].À_åÀ_倛À`4!/// {@macro riverpod.autoDispose}À^’À^’À^’À^™À^™À^™À^ÚÀ^ÚCÀ_À_%À_% À_-À_7À_7(À_SÀ^MÀ^M�”À^�/// {@macro riverpod.family}À]³À]³‚ÏÀ]Þ$/// Builds a [FutureProviderFamily].À`êÀ`ÿÀ`ÃÀ`Ã?/// Builds a [StreamProvider].Àb{Àb{€�ÀbÄ!/// {@macro riverpod.autoDispose}ÀcÀc{ÀcM/// {@macro riverpod.family}ÀaEÀaEÀaEÀaˆÀaˆ6Àa¸ÀaÆÀaÆ ÀaÎÀaØÀaØ(ÀaôÀaÀa�qÀa@!/// {@macro riverpod.autoDispose}À`„À`„ƒÀ`©/// Builds a [StreamProvider].ÀdÀd ÀcØÀcØK$/// Builds a [StreamProviderFamily].Àe½Àe½€›Àf !/// {@macro riverpod.autoDispose}ÀdlÀdlÀdlÀdsÀdsÀdsÀd´Àd´AÀdïÀdýÀdý ÀeÀeÀe(Àe+Àd'Àd'�’Àdg/// {@macro riverpod.family}Àc�Àc�‚ÍÀc¸$/// Builds a [StreamProviderFamily].ÀfàÀfÿÀf¯Àf¯S(/// Builds a [AutoDisposeStateProvider].Àh‘Àh‘€�ÀhÚ/// {@macro riverpod.family}ÀgOÀgOÀgOÀg’Àg’8ÀgÄÀgÒÀgÒ ÀgÚÀgäÀgä(ÀhÀgÀg�‡ÀgJ!/// {@macro riverpod.autoDispose}Àf\Àf\‚ÆÀf‹(/// Builds a [AutoDisposeStateProvider].ÀiºÀißÀiƒÀiƒ_./// Builds a [AutoDisposeStateProviderFamily].Àj5Àj5Àj5Àj<Àj<Àj<Àj}Àj}CÀjºÀjÈÀjÈ ÀjÐÀjÚÀjÚ(ÀjöÀiæÀiæ�¨Àj0/// {@macro riverpod.family}Ài$Ài$‚lÀiY./// Builds a [AutoDisposeStateProviderFamily].Àl.ÀlUÀkõÀkõc0/// Builds a [AutoDisposeStateNotifierProvider].ÀnUÀnU€ŸÀn¦/// {@macro riverpod.family}Àl½Àl½%Àl½ÀläÀläÀläÀm'Àm'UÀmvÀm„Àm„ ÀmŒÀm–Àm–(Àm²Àl\Àl\�õÀl¸!/// {@macro riverpod.autoDispose}Àk’Àk’ƒdÀkÉ0/// Builds a [AutoDisposeStateNotifierProvider].Ào¦ÀoÓÀogÀogo6/// Builds a [AutoDisposeStateNotifierProviderFamily].ÀpAÀpA%ÀpAÀphÀphÀphÀpoÀpoÀpoÀp°Àp°lÀqÀq$Àq$ Àq,Àq6Àq6(ÀqRÀoÚÀoÚ‚"Àp</// {@macro riverpod.family}ÀnøÀnøƒÀo56/// Builds a [AutoDisposeStateNotifierProviderFamily].ÀruÀr�ÀrIÀrII#/// Builds a [AutoDisposeProvider].ÀtÀt€…ÀtV/// {@macro riverpod.family}ÀrÚÀrÚÀrÚÀsÀs3ÀsJÀsXÀsX Às`ÀsjÀsj(Às†Àr–Àr–�xÀrÕ!/// {@macro riverpod.autoDispose}ÀrÀr‚™Àr*#/// Builds a [AutoDisposeProvider].Àu"ÀuBÀtðÀtðU)/// Builds a [AutoDisposeProviderFamily].Àu“Àu“Àu“ÀušÀušÀušÀuÛÀuÛ>ÀvÀv!Àv! Àv)Àv3Àv3(ÀvOÀuIÀuI�™ÀuŽ/// {@macro riverpod.family}Àt›Àt›‚IÀtË)/// Builds a [AutoDisposeProviderFamily].ÀwmÀw�Àw;Àw;U)/// Builds a [AutoDisposeFutureProvider].Ày,Ày,€‘Àyv/// {@macro riverpod.family}ÀwÞÀwÞÀwÞÀx!Àx!CÀx^ÀxlÀxl ÀxtÀx~Àx~(ÀxšÀw”Àw”�”ÀwÙ!/// {@macro riverpod.autoDispose}ÀvæÀvæ‚ÙÀw)/// Builds a [AutoDisposeFutureProvider].ÀzZÀz€Àz"Àz"a//// Builds a [AutoDisposeFutureProviderFamily].Àz×Àz×Àz×ÀzÞÀzÞÀzÞÀ{À{VÀ{oÀ{}À{} À{…À{�À{�(À{«Àz‡Àz‡�½ÀzÒ/// {@macro riverpod.family}ÀyÁÀyÁ‚…Ày÷//// Builds a [AutoDisposeFutureProviderFamily].À|ÏÀ|ïÀ|�À|�U)/// Builds a [AutoDisposeStreamProvider].À~ŒÀ~Œ€‘À~Ö/// {@macro riverpod.family}À}@À}@À}@À}ƒÀ}ƒAÀ}¾À}ÌÀ}Ì À}ÔÀ}ÞÀ}Þ(À}úÀ|öÀ|ö�’À};!/// {@macro riverpod.autoDispose}À|HÀ|H‚×À|x)/// Builds a [AutoDisposeStreamProvider].ÀºÀàÀ‚À‚a//// Builds a [AutoDisposeStreamProviderFamily].À€7À€7À€7À€>À€>À€>À€À€TÀ€ÍÀ€ÛÀ€Û À€ãÀ€íÀ€í(À� ÀçÀç�»À€2/// {@macro riverpod.family}À!À!‚ƒÀW//// Builds a [AutoDisposeStreamProviderFamily].„9*-€–€™€Ç���O�±�²�Ç�ü�ý‚‚‚=‚b‚Š‚²‚³‚ׂýƒ0ƒSƒeƒ“ƒšƒÊƒØƒê„ „„„„<„x„´„¸„¹„Ø… …A…E…G…H…t…Ÿ…Í…û…ü††L†�†²†Ä†ò†ù‡4‡B‡T‡v‡}‡�‡‚‡¦‡èˆ*ˆ.ˆ0ˆ1ˆbˆ’ˆÅˆøˆù‰‰N‰Œ‰¯‰Á‰ï‰öŠ1Š?ŠQŠsŠzŠ~ŠŠžŠÛ‹‹!‹#‹$‹[‹‘‹ÊŒŒŒ#Œ_Œ­ŒÐŒâ���]�k�}�Ÿ�¦�ª�¬�­�Î�4Ž5ŽYŽ~Ž´Ž×Žé���M�[�m���–�š�›�¿�ö�-�1�2�Q�~�°�´�¶�·�Þ‘‘-‘V‘W‘v‘¦‘ì’’!’O’V’�’ž’°’Ò’Ù’Ý’Þ““?“|“€“‚“ƒ“¯“Ú””6”7”[”‹”̔/•6•p•~•�•²•¹•½•¾•Ý––R–V–X–Y–‹–¼–ð—$—%—D——Зó˜˜3˜:˜˜�˜Ÿ˜Á˜È˜Ì˜Î˜Ï˜ö™™E™n™o™“™º™îšš#šQšXš‰š—š©šËšÒšÖš×šû›8›u›y›z›™›Ìœœœ œ œ8œdœ“œÂœÃœâ��X�{���»�Â�þž žž@žGžKžLžpž³žöžúžüžýŸ/Ÿ`Ÿ”ŸÈŸÉŸí  ^ � “ Á È¡¡¡$¡F¡M¡Q¡R¡q¡¯¡ò¡ö¡ø¡ù¢1¢h¢¢¢Ü¢Ý¢ü£9£ˆ£«£½£ë£ò¤9¤G¤Y¤{¤‚¤†¤ˆ¤‰¤§¤Ä¤ä¥¥¥,¥{¥�¥Ÿ¥¥¥ð¦E¦‡¦Ô¦ñ§H§N§«§±¨¨A¨G¨—¨¨¨®¨¼¨þ©2©K©d©n©x©~©ÐªªQª’ª˜ªè«1«ƒ«‰«—«Ù¬¬7¬=¬‡¬·¬Ð¬é¬ó¬ý­­6­m­¢­´­â­é® ®®*®L®S®W®X®|®°®ä®è®é¯ ¯Z¯`¯¯¯Ò¯Ø°°°&°r° °Ä°ù±±*±6±<±K±Q±c±Ÿ±Ù±ß²²e²�²£²Á²Ë²×²Ý³%³+³;³�³Ð´´´´&´,´>´z´³´¹´üµFµŸµÕ¶ ¶¶-¶Z¶˜¶Ð¶Ý¶ç¶ó¶ù·S·Y·i·ä¸(¸x¸°¸¼¸È¸Î¸Ý¸ã¹1¹„¹Š¹Ö¹õ¹ûº º_º™º£º­º³» »»!»/»i»�»Ñ»Ù»ã»é¼¼F¼L¼Z¼”¼Î¼Ö¼à¼æ½7½„½À½Æ½Ô½ä¾¾f¾¯¾µ¾ð¾ø¿¿¿'¿-¿~¿¹¿¿À@À@jÀ@pÀ@vÀ@ÁÀ@üÀAÀAÀAnÀAzÀA†ÀAŒÀAÞÀAøÀAþÀB.ÀB4ÀB‡ÀB�ÀBáÀCÀCÀC*ÀCRÀC…ÀC²ÀC¸ÀCÍÀCõÀD2ÀDBÀDSÀD‹ÀD«ÀDÌÀDðÀE ÀEÀEÀEzÀEŸÀEÄÀEñÀEýÀFÀFÀFQÀFŠÀFÄÀFÊÀFñÀG;ÀGHÀGRÀG^ÀGdÀG›ÀG«ÀGÚÀGúÀHÀH>ÀHLÀHRÀHnÀHŒÀH’ÀH¦ÀHÜÀHæÀHìÀIIÀInÀI“ÀIÀÀIÌÀIÒÀIäÀJ ÀJYÀJ“ÀJ™ÀJÀÀK ÀKÀK!ÀK-ÀKBÀKlÀK›ÀKŸÀK¡ÀK¢ÀKÆÀKéÀLÀL5ÀL6ÀLUÀL‰ÀLÀÀMÀMÀM@ÀMGÀMsÀM�ÀM“ÀMµÀM¼ÀMÀÀMÁÀMåÀNÀNYÀN]ÀN_ÀN`ÀN†ÀN«ÀNÓÀNûÀNüÀO ÀOIÀOƒÀOºÀPÀPÀPDÀPKÀP~ÀPŒÀPžÀPÀÀPÇÀPËÀPÌÀPðÀQ,ÀQhÀQlÀQmÀQŒÀQ¾ÀQõÀQùÀQûÀQüÀR(ÀRSÀR�ÀR¯ÀR°ÀRÏÀSÀSBÀSyÀSÄÀSÖÀSèÀTÀTÀT[ÀTiÀT{ÀT�ÀT¤ÀT¨ÀT©ÀTÍÀUÀUQÀUUÀUWÀUXÀUqÀU‰ÀU¤ÀU¿ÀUÀÀUäÀVÀV:ÀVjÀV|ÀVªÀV±ÀVÍÀVÛÀVíÀWÀWÀWÀWÀW?ÀWnÀW�ÀW¡ÀW¢ÀWÁÀWæÀXÀXÀXÀXÀX6ÀXTÀXuÀX–ÀX—ÀX¶ÀXåÀYÀYWÀYiÀY—ÀYžÀYÅÀYÓÀYåÀZÀZÀZÀZÀZ7ÀZlÀZ¡ÀZ¥ÀZ§ÀZ¨ÀZÇÀZåÀ[À['À[(À[LÀ[qÀ[¨À[èÀ[úÀ\(À\/À\QÀ\_À\qÀ\“À\šÀ\žÀ\ŸÀ\ÃÀ\øÀ]-À]1À]2À]QÀ]|À]¬À]°À]²À]³À]ØÀ]üÀ^#À^JÀ^KÀ^jÀ^ŸÀ^ÖÀ_!À_3À_aÀ_hÀ_•À_£À_µÀ_×À_ÞÀ_âÀ_ãÀ`À`BÀ`}À`�À`ƒÀ`„À`£À`ÁÀ`âÀaÀaÀa(ÀaMÀa„ÀaÂÀaÔÀbÀb Àb+Àb9ÀbKÀbmÀbtÀbxÀbyÀb�ÀbÒÀcÀc Àc Àc+ÀcVÀc†ÀcŠÀcŒÀc�Àc²ÀcÖÀcýÀd$Àd%ÀdDÀdyÀd°ÀdùÀe Àe9Àe@ÀemÀe{Àe�Àe¯Àe¶ÀeºÀe»ÀeßÀfÀfUÀfYÀf[Àf\Àf…Àf­ÀfØÀgÀgÀg(ÀgWÀgŽÀgÎÀgàÀhÀhÀhAÀhOÀhaÀhƒÀhŠÀhŽÀh�Àh®ÀhãÀiÀi!Ài#Ài$ÀiSÀi�Ài²ÀiãÀiäÀjÀjBÀjyÀjÄÀjÖÀkÀk ÀkBÀkPÀkbÀk„Àk‹Àk�Àk‘Àk’ÀkÃÀkóÀl&ÀlYÀlZÀl~Àl²ÀlìÀm#ÀmnÀm€Àm’ÀmÀÀmÇÀnÀnÀn%ÀnGÀnNÀnRÀnSÀnrÀn¯ÀnñÀnõÀn÷ÀnøÀo/ÀoeÀožÀo×ÀoØÀo÷Àp6ÀpuÀp¬ÀpýÀqÀq Àq2Àq`ÀqgÀq°Àq¾ÀqÐÀqòÀqùÀqýÀqÿÀrÀr$ÀrGÀrmÀr“Àr”Àr¸ÀrâÀsÀsTÀsfÀs”Às›ÀsÂÀsÐÀsâÀtÀt ÀtÀtÀt/Àt_Àt”Àt˜ÀtšÀt›ÀtÅÀtîÀuÀuFÀuGÀufÀu Àu×ÀvÀv/Àv]ÀvdÀv–Àv¤Àv¶ÀvØÀvßÀvãÀvåÀvæÀwÀw9ÀweÀw‘Àw’Àw¶ÀwæÀxÀxhÀxzÀx¨Àx¯ÀxÜÀxêÀxüÀyÀy%Ày)Ày*ÀyIÀyÀyºÀy¾ÀyÀÀyÁÀyñÀz ÀzRÀz„Àz…Àz¤ÀzäÀ{À{gÀ{yÀ{‹À{¹À{ÀÀ{øÀ|À|À|:À|AÀ|EÀ|GÀ|HÀ|rÀ|›À|ÇÀ|óÀ|ôÀ}À}HÀ}À}ÈÀ}ÚÀ~À~À~<À~JÀ~\À~~À~…À~‰À~ŠÀ~©À~ßÀÀÀ À!ÀQÀ€À²ÀäÀåÀ€À€DÀ€{À€ÅÀ€×À€éÀ�À�À�VÀ�dÀ�vÀ�˜À�ŸÀ�£À�¥ AsyncNotifierProviderBuilder"AsyncNotifierProviderFamilyBuilder'AutoDisposeAsyncNotifierProviderBuilder-AutoDisposeAsyncNotifierProviderFamilyBuilderNotifierProviderBuilderNotifierProviderFamilyBuilder"AutoDisposeNotifierProviderBuilder(AutoDisposeNotifierProviderFamilyBuilderStreamNotifierProviderBuilder#StreamNotifierProviderFamilyBuilder(AutoDisposeStreamNotifierProviderBuilder.AutoDisposeStreamNotifierProviderFamilyBuilderStateProviderBuilderStateProviderFamilyBuilderStateNotifierProviderBuilder"StateNotifierProviderFamilyBuilderProviderBuilderProviderFamilyBuilderFutureProviderBuilderFutureProviderFamilyBuilderStreamProviderBuilderStreamProviderFamilyBuilderAutoDisposeStateProviderBuilder%AutoDisposeStateProviderFamilyBuilder'AutoDisposeStateNotifierProviderBuilder-AutoDisposeStateNotifierProviderFamilyBuilderAutoDisposeProviderBuilder AutoDisposeProviderFamilyBuilder AutoDisposeFutureProviderBuilder&AutoDisposeFutureProviderFamilyBuilder AutoDisposeStreamProviderBuilder&AutoDisposeStreamProviderFamilyBuilderriverpod.autoDispose†ÀMarks the provider as automatically disposed when no longer listened to. Some typical use-cases: - Combined with [StreamProvider], this can be used as a mean to keep the connection with Firebase alive only when truly needed (to reduce costs). - Automatically reset a form state when leaving the screen. - Automatically retry HTTP requests that failed when the user exit and re-enter the screen. - Cancel HTTP requests if the user leaves a screen before the request completed. Marking a provider with `autoDispose` also adds an extra method on `ref`: `keepAlive`. The `keepAlive` function is used to tell Riverpod that the state of the provider should be preserved even if no longer listened to. A use-case would be to set this flag to `true` after an HTTP request have completed: ```dart final myProvider = FutureProvider.autoDispose((ref) async { final response = await httpClient.get(...); ref.keepAlive(); return response; }); ``` This way, if the request failed and the UI leaves the screen then re-enters it, then the request will be performed again. But if the request completed successfully, the state will be preserved and re-entering the screen will not trigger a new request. It can be combined with `ref.onDispose` for more advanced behaviors, such as cancelling pending HTTP requests when the user leaves a screen. For example, modifying our previous snippet and using `dio`, we would have: ```diff final myProvider = FutureProvider.autoDispose((ref) async { + final cancelToken = CancelToken(); + ref.onDispose(() => cancelToken.cancel()); + final response = await dio.get('path', cancelToken: cancelToken); - final response = await dio.get('path'); ref.keepAlive(); return response; }); ```riverpod.family—yA group of providers that builds their value from an external parameter. Families can be useful to connect a provider with values that it doesn't have access to. For example: - Allowing a "title provider" access the `Locale` ```dart final titleFamily = Provider.family((ref, locale) { if (locale == const Locale('en')) { return 'English title'; } else if (locale == const Locale('fr')) { return 'Titre Français'; } }); // ... @override Widget build(BuildContext context, WidgetRef ref) { final locale = Localizations.localeOf(context); // Obtains the title based on the current Locale. // Will automatically update the title when the Locale changes. final title = ref.watch(titleFamily(locale)); return Text(title); } ``` - Have a "user provider" that receives the user ID as a parameter ```dart final userFamily = FutureProvider.family((ref, userId) async { final userRepository = ref.read(userRepositoryProvider); return await userRepository.fetch(userId); }); // ... @override Widget build(BuildContext context, WidgetRef ref) { int userId; // Read the user ID from somewhere // Read and potentially fetch the user with id `userId`. // When `userId` changes, this will automatically update the UI // Similarly, if two widgets tries to read `userFamily` with the same `userId` // then the user will be fetched only once. final user = ref.watch(userFamily(userId)); return user.when( data: (user) => Text(user.name), loading: () => const CircularProgressIndicator(), error: (err, stack) => const Text('error'), ); } ``` - Connect a provider with another provider without having a direct reference on it. ```dart final repositoryProvider = Provider.family>((ref, configurationsProvider) { // Read a provider without knowing what that provider is. final configurations = await ref.read(configurationsProvider.future); return Repository(host: configurations.host); }); ``` ## Usage The way families works is by adding an extra parameter to the provider. This parameter can then be freely used in our provider to create some state. For example, we could combine `family` with [FutureProvider] to fetch a `Message` from its ID: ```dart final messagesFamily = FutureProvider.family((ref, id) async { return dio.get('http://my_api.dev/messages/$id'); }); ``` Then, when using our `messagesFamily` provider, the syntax is slightly modified. The usual: ```dart Widget build(BuildContext context, WidgetRef ref) { // Error – messagesFamily is not a provider final response = ref.watch(messagesFamily); } ``` will not work anymore. Instead, we need to pass a parameter to `messagesFamily`: ```dart Widget build(BuildContext context, WidgetRef ref) { final response = ref.watch(messagesFamily('id')); } ``` **NOTE**: It is totally possible to use a family with different parameters simultaneously. For example, we could use a `titleFamily` to read both the french and english translations at the same time: ```dart @override Widget build(BuildContext context, WidgetRef ref) { final frenchTitle = ref.watch(titleFamily(const Locale('fr'))); final englishTitle = ref.watch(titleFamily(const Locale('en'))); return Text('fr: $frenchTitle en: $englishTitle'); } ``` # Parameter restrictions For families to work correctly, it is critical for the parameter passed to a provider to have a consistent `hashCode` and `==`. Ideally the parameter should either be a primitive (bool/int/double/String), a constant (providers), or an immutable object that override `==` and `hashCode`. - **PREFER** using `family` in combination with `autoDispose` if the parameter passed to providers is a complex object: ```dart final example = Provider.autoDispose.family((ref, param) { }); ``` This ensures that there is no memory leak if the parameter changed and is never used again. # Passing multiple parameters to a family Families have no built-in support for passing multiple values to a provider. On the other hand, that value could be _anything_ (as long as it matches with the restrictions mentioned previously). This includes: - A tuple (using `package:tuple`) - Objects generated with Freezed/built_value - Objects based on `package:equatable` This includes: - A tuple (using `package:tuple`) - Objects generated with Freezed/built_value, such as: ```dart @freezed abstract class MyParameter with _$MyParameter { factory MyParameter({ required int userId, required Locale locale, }) = _MyParameter; } final exampleProvider = Provider.family((ref, myParameter) { print(myParameter.userId); print(myParameter.locale); // Do something with userId/locale }); @override Widget build(BuildContext context, WidgetRef ref) { int userId; // Read the user ID from somewhere final locale = Localizations.localeOf(context); final something = ref.watch( exampleProvider(MyParameter(userId: userId, locale: locale)), ); } ``` - Objects based on `package:equatable`, such as: ```dart class MyParameter extends Equatable { factory MyParameter({ required this.userId, requires this.locale, }); final int userId; final Local locale; @override List get props => [userId, locale]; } final exampleProvider = Provider.family((ref, myParameter) { print(myParameter.userId); print(myParameter.locale); // Do something with userId/locale }); @override Widget build(BuildContext context, WidgetRef ref) { int userId; // Read the user ID from somewhere final locale = Localizations.localeOf(context); final something = ref.watch( exampleProvider(MyParameter(userId: userId, locale: locale)), ); } ```_Ë