'Why my Listview is continuously adding the same data from API , I am using Flutter Provider?

Here is the ProviderModel:

class UserModel extends ChangeNotifier {
  User user = new User(
  name: 'Loading name...',
  avatarUrl:
     'https://i.pinimg.com/564x/10/b2/f6/10b2f6d95195994fca386842dae53bb2.jpg',
  email: 'as',
  id: 'asfd',
  createdAt: 'as',
  jwt: 'asfe',
  tasks: [
    Task(
       title: "Loading data..",
       description: "loading data..",
       isCompleted: true),
  ],
 );


 Future<String> getMyTasks() async {
  final String token = user.jwt;

  try {
    final response = await http.get(
      Uri.parse('$serverUrl/tasks?sortBy=createdAt:asc'),
       headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Authorization': 'Bearer $token',
    },
  );

  var res = response.body;
  return res;
} catch (e) {
  print('Got an Error : $e');
}
}






  void updateTasks() async {
try {
  var myTasks = jsonDecode(await getMyTasks());
  myTasks.forEach((task) {
    Task tempTask = Task(
        title: task["description"],
        isCompleted: task["completed"],
        description: "No description");
    user.tasks.add(tempTask);
    notifyListeners();
  });
} catch (e) {
  print('Encountered an Error while retriving tasks from the server');
  print(e);
}
 }

And here is the Widget that uses data from this Provider:

class AllTasks extends StatelessWidget {
@override
Widget build(BuildContext context) {
context.watch<UserModel>().updateProfile();
context.watch<UserModel>().updateTasks();

print('AllTask Widget Builded...');
return ListView.separated(
  itemCount: context.watch<UserModel>().user.tasks.length,
  physics: NeverScrollableScrollPhysics(),
  shrinkWrap: true,
  itemBuilder: (BuildContext context, int index) {
    return ListTile(
      leading: Text((index + 1).toString()),
      title: Text(context.watch<UserModel>().user.tasks[index].title,
          style: GoogleFonts.ubuntu()),
      subtitle: Text(
          context.watch<UserModel>().user.tasks[index].description,
          style: GoogleFonts.ubuntu()),
      trailing: Checkbox(
        value: context.watch<UserModel>().user.tasks[index].isCompleted,
        onChanged: (value) {},
      ),
    );
  },
  separatorBuilder: (BuildContext context, int index) => Padding(
    padding: const EdgeInsets.symmetric(horizontal: 50.0),
    child: const Divider(
      thickness: 1.0,
    ),
  ),
);
}
}

Can Anyone Please help me ? The build method of AllTask Widget gets rebuilded everytime Because of Which the same data from the API gets Added to the taskList Of user...And the ListView shows the same data continuously without stopping. Is there any solution?



Solution 1:[1]

remove these from inside the build otherwise update tasks will get called continuously during the build resulting in a loop. you can place them in initState.

context.watch<UserModel>().updateProfile();
context.watch<UserModel>().updateTasks();

Solution 2:[2]

Because you're calling your functions in the build method. And build method is being called again and again, hence adding the same data in your list that you provided your ListView.builder. Remove these lines of code from the build method.

context.watch<UserModel>().updateProfile();
context.watch<UserModel>().updateTasks();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nikhil Biju
Solution 2 Usman Akhlaq