I’m building a simple note-taking app, all the notes are being fetched from the backend ‘localhost’. when I first log in and navigate to the notes_screen.dart
the app doesn’t show the notes, even though they have been fetched and are being added to the list! but the stranger thing is when I hot reload the app the list does appear!!
here is my NotesScreen
:
import 'package:flutter/material.dart';
import 'package:flutter_lorem/flutter_lorem.dart';
import 'package:get/get.dart';
import 'package:logging/logging.dart';
import 'package:notes_app/controllers/login_controller.dart';
import 'package:notes_app/controllers/notes_controller.dart';
import 'package:notes_app/screens/empty_state_screen.dart';
import 'package:notes_app/screens/notes/note_viewer_screen.dart';
import '../../widgets/note_card.dart';
import 'new_note.dart';
class NotesPage extends GetWidget<NotesController> {
final log = Logger("NotesPage");
NotesPage({super.key});
LoginController loginController = Get.find<LoginController>();
@override
Widget build(BuildContext context) {
return Scaffold(
// some code
body: Obx(
() => controller.isNotesListEmpty()
? const Center(child: EmptyState())
: Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.builder(
itemCount: controller.notesList.value.length,
itemBuilder: (context, index) {
return Dismissible(
key: UniqueKey(),
secondaryBackground: Container(
color: Colors.red,
child: const Center(
child: Icon(Icons.delete_forever),
),
),
background: Container(color: Colors.red),
onDismissed: (direction) {
controller
.deleteNote(controller.notesList.value[index].id);
},
child: NoteCard(
note: controller.notesList.value[index],
onTap: () async {
Get.to(() => NoteViewer(),
arguments: controller.notesList.value[index]);
},
onLongPress: () async {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('delete_msg'.tr),
actions: [
TextButton(
onPressed: () {
controller.deleteNote(controller
.notesList.value[index].id);
},
child: Text('yes'.tr),
),
TextButton(
onPressed: () {
Get.back();
},
child: Text('no'.tr),
),
],
);
},
);
},
),
);
}),
),
),
// some code
);
}
}
My NotesController
:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:logging/logging.dart';
import 'package:notes_app/models/new_note_model.dart';
import 'package:notes_app/models/note_model.dart';
import 'package:notes_app/screens/notes/home_screen.dart';
import 'package:notes_app/services/rest_apis.dart';
class NotesController extends GetxController {
final log = Logger("NotesController");
Rx<List<Note>> notesList = Rx<List<Note>>([]);
var titleController = TextEditingController();
var contentController = TextEditingController();
RestAPIs restAPI = Get.find<RestAPIs>();
@override
void onInit() {
super.onInit();
getAllNotes();
ever(notesList, (callback) => null);
}
@override
void onClose() {
log.fine("The controller has been deleted");
}
bool isNotesListEmpty() {
if (notesList.value.isEmpty) {
log.warning("The list notes is Empty!");
return true;
} else {
log.fine("The list notes is not Empty!");
return false;
}
}
Future getAllNotes() async {
var results = await restAPI.fetchAllNotes();
List<Note> notes = List.generate(
results.length,
(index) => Note.fromJson(results[index]),
);
log.info("The length of the notesList ${notes.length.toString()}");
notesList.value.addAll(notes);
}
here is my log when I run the app
[GETX] Instance "NotesController" has been created
[GETX] Instance "NotesController" has been initialized
I/flutter ( 4179): WARNING: 2023-10-15 04:58:45.435093: The list notes is Empty!
I/flutter ( 4179): INFO: 2023-10-15 04:58:45.577467: The length of the notesList 10
as you can see after the ‘NotesController’ is created and initializing the data is saved on the list, note that the log shows that the list is empty because the response hasn’t come through yet, after that the data arrived, but the screen doesn’t update
2
Answers
I had exactly this problem and I solved it by the following :
in the
NotesController
in the
NotesScreen
:I know there is other solutions but this looks good to me. Hopefully it helps.
You could call just
.addAll()
not.value.addAll()
.Because
.value.addAll()
is for only adding,but
.addAll()
of RxList is for adding and refreshing.