3

I am able to share data between widgets when the widgets are int he same file but when the widgets are in different files, the ui does not rebuild and i do not seem to get it right.

Please kindly check my codes below and see where I'm falling short. (I added image for easy reading and text code for easy CTRL C - CTRL V)

Objective

I'm trying to share data between multiple widgets in different files IMAGE HERE

but it doesn't notify the other widgets / rebuild When button at line 45 is tapped, text at line 44 change successfully but screen at line 26 doesn't change

//--------------navigation_provider.dart----------------//

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class NavigationProvider extends ChangeNotifier{

bool showUserProfile = true;
  
void toggleProfile(toggle){
showUserProfile = toggle;
notifyListeners();
}
}

//--------------desktop_scaffold.dart----------------//

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:premiumpeaches/providers/navigation_provider.dart';
import 'package:flutter/material.dart';

final navigatorProvider = ChangeNotifierProvider((ref) => NavigationProvider());
class DesktopScaffold extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return SizedBox(
      child: ref.watch(navigatorProvider).showUserProfile == true ? UserProfileComponent() : ProfileSettingsComponent()
    )
  
}

//--------------user_profile_component.dart----------------//

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:premiumpeaches/providers/navigation_provider.dart';
import 'package:flutter/material.dart';

final navigatorProvider = ChangeNotifierProvider((ref) => NavigationProvider());
class UserProfileComponent extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return InkWell(
onTap:(){
ref.watch(navigatorProvider).toggleProfile(false);
},
child:Text('Click Me')
)
  
}
ket-c
  • 211
  • 1
  • 10

1 Answers1

6

You defined navigatorProvider twice.

That's likely the source of your problem. Two providers mean two different states. So interacting with one navigatorProvider has no effect on the other

Rather than defining navigatorProvider twice, you most likely instead want to import it.

For example inside desktop_scaffold.dart you could do:

import 'user_profile_component.dart';

You can then use navigatorProvider all the same. But now, you only have a single navigatorProvider, so all interactions goes through that one.

Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432
  • I defined ```NavigatorProvider``` separately in in different files. How do I use one for all – ket-c Dec 13 '22 at 14:13
  • after i did ```import 'user_profile_component.dart';``` in **desktop_scaffold**, I passed the ChangeNotifierProvider to user_profile_component using ```UserProfileComponent(navigatorProvider)``` but when i tried to do a watch in user_profile_component using ```ref.watch(this.widget.navigatorProvider)!.showUserProfile.toString()```, i got an error message that **"The getter 'showUserProfile' isn't defined for the type 'ChangeNotifier'."** – ket-c Dec 13 '22 at 15:01
  • You didn't do what I told you. I said to just remove the second provider and add an import. Do nothing else. – Rémi Rousselet Dec 13 '22 at 15:30
  • So I had to also import **desktop_scaffold.dart** in **user_profile_component.dart** to be able to access it's ChangeNotifierProvider and i was able to use ```ref.watch(navigatorProvider).showUserProfile.toString()``` in user_profile_component and it worked Thanks to @saytoonz https://stackoverflow.com/users/10117989/saytoonz for some insight – ket-c Dec 13 '22 at 15:51
  • So I've revised my code by defining ``` final navigatorProvider = ChangeNotifierProvider((ref) => NavigationProvider()``` in my constants.dart and imported **constant.dart** anywhere needed.... Thanks. Your answer gave me much insight and comprehension. I appreciate a lot. – ket-c Dec 13 '22 at 16:33