Reputation: 1
I have created an observable list and then storing data in the list from the api as below
class FeedsController extends GetxController {
final Rx<List<Stories>> _stories = Rx<List<Stories>>([]);
@override
void onInit() {
super.onInit();
getActiveStories();
}
List<Stories> get getStories {
return _stories.value;
}
Future<List<Stories>> getActiveStories() async {
var url = Uri.parse(storiesURL);
Map<String, Object> params = {'apikey': apiKey, 'userid': "8"};
await http.post(url, body: params).then((value) {
StoriesResponse storiesResponse = storiesResponseFromJson(value.body);
_stories.value = storiesResponse.stories;
}).onError((error, stackTrace) {
debugPrint('Error occurred while fetching stories response: ${error.toString()}');
});
return _stories.value;
}
}
Here is the code for displaying the Stories List
class _ActiveStoriesListState extends State<ActiveStoriesList> {
List<Story> _currentUserStories = [];
final FeedsController _feedsController = Get.find();
@override
void initState() {
Future.delayed(Duration.zero, fetchUserStories);
super.initState();
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Active Stories',
style: titleLargeTextStyle.copyWith(fontSize: 22, fontWeight: FontWeight.w600),),
const SizedBox(height: 10),
SizedBox(
height: 100,
child: Obx(
() => ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (ctx, index) =>
ActiveStoriesWidget(story: _currentUserStories[index]),
itemCount: _currentUserStories.length,
),
)),
],
);
}
void fetchUserStories() async {
List<Stories> stories = _feedsController.getStories;
stories = stories.where((story) => story.userId == '8').toList();
_currentUserStories = stories[0].story;
debugPrint('Active Stories Page: ${_currentUserStories.length}');
}
}
Solutions I have tried is that make only ListView observable (that didn't work), making ListView parent child Observable that also didn't work. I'm unable to understand where I'm missing. Below is the exception
sample json data
{ "status": 200, "success": [ { "user_id": "4", "first_name": "Abu", "profileImage": "jayspur.com/RallyApp/public/uploads/userImages/…", "story": [ { "story": "jayspur.com/RallyApp/public/uploads/userStories/…", "addeddate": "2023-02-08 09:58:11" } ] } ] }
Upvotes: 0
Views: 371
Reputation: 1253
You are getting this error because you are not using any observable list inside your ListView.builder
.
But before that you should convert your StatefullWidget
to a StatelessWidget
because in GetX, we don't need any StatefullWidget
.
You can try the following code.
Controller
class FeedsController extends GetxController {
final Rx<List<Stories>> _stories = Rx<List<Stories>>([]);
List<Stories> currUserstories = [];
RxBool isLoading = false.obs;
@override
void onInit() {
super.onInit();
getActiveStories();
}
List<Stories> get getStories {
return _stories.value;
}
Future<List<Stories>> getActiveStories() async {
isLoading.value = true;
var url = Uri.parse("storiesURL");
Map<String, Object> params = {'apikey': apiKey, 'userid': "8"};
await http.post(url, body: params).then((value) {
StoriesResponse storiesResponse = storiesResponseFromJson(value.body);
_stories.value = storiesResponse.stories;
_stories.value =
_stories.value.where((story) => story.userId == '8').toList();
currUserstories = _stories.value[0];
}).onError((error, stackTrace) {
debugPrint(
'Error occurred while fetching stories response: ${error.toString()}');
});
isLoading.value = false;
return _stories.value;
}
}
View file:
class ActiveStoriesList extends StatelessWidget {
ActiveStoriesList({super.key});
final FeedsController _feedsController = Get.find();
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Active Stories',
style: titleLargeTextStyle.copyWith(
fontSize: 22, fontWeight: FontWeight.w600),
),
const SizedBox(height: 10),
SizedBox(
height: 100,
child: Obx(
() => _feedsController.isLoading.value
? const Center(
child: CircularProgressIndicator(),
)
: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: (ctx, index) => ActiveStoriesWidget(
story: _feedsController.currUserstories[index]),
itemCount: _feedsController.currUserstories.length,
),
)),
],
);
}
}
You might have to tweak the code a bit but the core concept it you should do all your work inside the controller and only fetch the data in view file.
Also, you should only use the lifecycle which controller provides. Eg. onInit
instead of initState
.
If this dosen't work, try to modify your controller file such that you get the value in the list as you want in the controller file itself and you the list which was preseneted in controller in your view file.
Hope it helps.
Upvotes: 1