Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why list not updating? #401

Closed
tony123S opened this issue Dec 11, 2023 · 7 comments
Closed

Why list not updating? #401

tony123S opened this issue Dec 11, 2023 · 7 comments
Assignees
Labels
bug Something isn't working needs triage

Comments

@tony123S
Copy link

tony123S commented Dec 11, 2023

In page A, I'm calling an API to get list data from server , then add it into list.

Page A code

Widget build(BuildContext context) { 

ValueNotifier<List> list = useState([]);

useEffect(() {
  WidgetsBinding.instance.addPostFrameCallback((_) {
    context
        .read<AgentVehiclesListCubit>()
        .getAgentVehiclesList(
            GetAgentVehiclesListParams(tenancyId: tenancy.id!))
        .whenComplete(() {
      final state = BlocProvider.of<AgentVehiclesListCubit>(context).state;
      if (state is AgentVehiclesListDone) {
        list.value = state.tenancy;  // add the output from server to list
      }
    });
  });

  return () {};
}, const []); 

When Button is pressed, pass the list to EditScreen.

InkWell(
   onTap: () {
     Navigator.pushNamed(
        context, TenancyRoutes.editScreen,
        arguments: list);
},

In EditScreen, there is a floatingActionButton for user to add vehicleItems. Once added, the item should be added into the list, and Listview should be refreshed.

class EditScreen extends HookWidget {
      final ValueNotifier<List<VehicleItems>> list;
    
      const EditScreen(this.list, {super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          floatingActionButton: FloatingActionButton(
              backgroundColor: AppTheme.light.colorScheme.primary,
              onPressed: () {
                Navigator.pushNamed(context, TenancyRoutes.createVehicleItemsScreen)
                    .then(((onValue) {
                  if (onValue is VehicleItems) {
                    debugPrint(onValue.toString());
                    list.value = [...list.value..add(onValue)]; // add new item into here
                  }
                }));
              },
              child: const Icon(
                Icons.add,
                color: Colors.white,
              )),
          appBar: AppBar(
              iconTheme: const IconThemeData(color: Colors.white),
              backgroundColor: AppTheme.light.colorScheme.primary,
              title: Text(
                'vehicles'.tr(),
                style: const TextStyle(color: Colors.white),
              ),
              actions: const []),
          body: _showBody(list),
        );
      }
    
      Widget _showBody(ValueNotifier<List<VehicleItems>> list) {
        return ListView.separated(
            padding: EdgeInsets.zero,
            shrinkWrap: true,
            separatorBuilder: (context, index) => Padding(
                padding: const EdgeInsets.symmetric(horizontal: 20),
                child: Container(
                  color: Colors.grey.shade200,
                  height: 1,
                )),
            itemCount: list.value.length,
            itemBuilder: (context, index) {
              final items = list.value[index];
              return InkWell(
                  onTap: () {},
                  child: ListItemPadding(
                    child: VehicleItem(items),
                    // isDeleteVisible: false,
                  ));
            });
      }
    }

However, the listView remains unchanged unless I hot reload it. How to fix it?

@tony123S tony123S added bug Something isn't working needs triage labels Dec 11, 2023
@rrousselGit
Copy link
Owner

You're not listening to the ValueNotifier

Use useValueListenable(list);

@tony123S
Copy link
Author

tony123S commented Dec 11, 2023

You're not listening to the ValueNotifier

Use useValueListenable(list);

Sorry, I have edited my post to make it clearer. I'm using useState in Page A.
I have added useValueListenable after list.value = [...list.value..add(onValue)];, , but still same.

@rrousselGit
Copy link
Owner

My answer doesn't change. Use useValueListenable in EditScreen :)

@tony123S
Copy link
Author

tony123S commented Dec 11, 2023

Error after useValueListenable is added,


E/flutter (23009): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: 'package:flutter_hooks/src/framework.dart': Failed assertion: line 133 pos 12: 'HookElement._currentHookElement != null': Hooks can only be called from the build method of a widget that mix-in `Hooks`.
E/flutter (23009): 
E/flutter (23009): Hooks should only be called within the build method of a widget.
E/flutter (23009): Calling them outside of build method leads to an unstable state and is therefore prohibited.
E/flutter (23009): 
E/flutter (23009): #0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:51:61)
E/flutter (23009): #1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:40:5)
E/flutter (23009): #2      Hook.use (package:flutter_hooks/src/framework.dart:133:12)
E/flutter (23009): #3      use (package:flutter_hooks/src/framework.dart:18:32)
E/flutter (23009): #4      useValueListenable (package:flutter_hooks/src/listenable.dart:9:3)
E/flutter (23009): #5      EditScreen.build.<anonymous closure>.<anonymous closure> (package:xxx/edit_screen.dart:23:17)
E/flutter (23009): <asynchronous suspension>

Am I added it in the right place?

@tony123S
Copy link
Author

fixed.

Widget _showBody(ValueNotifier<List<VehicleItems>> list) {
  final vehicleList = useValueListenable(list); // useValueListenable put here instead
  return ListView.separated(
      padding: EdgeInsets.zero,
      shrinkWrap: true,
      separatorBuilder: (context, index) => Padding(
          padding: const EdgeInsets.symmetric(horizontal: 20),
          child: Container(
            color: Colors.grey.shade200,
            height: 1,
          )),
      itemCount: vehicleList.length,
      itemBuilder: (context, index) {
        final items = vehicleList[index];
        return InkWell(
            onTap: () {},
            child: ListItemPadding(
              child: VehicleItem(items),
              // isDeleteVisible: false,
            ));
      });
}

@soxft
Copy link

soxft commented Apr 11, 2024

I have the same questions, useValueListenable is still not working for me when using xx.value.add(1)
but xx.value = [...xx.value, 1] works

here is the code

class CampusMerchantHome extends HookWidget {
  const CampusMerchantHome({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final devices = useState<List<int>>([]);

    Future<void> initPrinter() async {
      devices.value.add(1);
    }

    Widget deviceItem(ValueNotifier<List<int>> device) {
      final deviceListener = useValueListenable(device);

      return ListView.builder(
        itemCount: deviceListener.length,
        itemBuilder: (context, index) {
          final deviceChoose = deviceListener[index];

          return ListTile(
            title: Text(deviceChoose.toString()),
          );
        },
      );
    }

    return Scaffold(
      appBar: AppBar(
        title: const Text("welcome to use 校悦送"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () => initPrinter(),
              child: const Text('initPrinter'),
            ),
            Expanded(
              child: deviceItem(devices),
            ),
          ],
        ),
      ),
    );
  }
}

@shahriarsihamstat
Copy link

I have the same questions, useValueListenable is still not working for me when using xx.value.add(1) but xx.value = [...xx.value, 1] works

@soxft I had the same problem, and your solution worked for me as well. Kudos!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs triage
Projects
None yet
Development

No branches or pull requests

4 participants