I have an app that displays 4 different charts. Initialization works fine, but as soon as I try to swipe between them (after refreshing the initial data, with the initial data swiping works fine), I get an error:
[Get] the improper use of a GetX has been detected. You should only use GetX or Obx for the specific widget that will be updated.
Here id the code for the PageView
import 'package:adminapp/controllers/controllerDashboard.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:adminapp/classes/globals.dart' as globals;
import 'package:get_storage/get_storage.dart';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:liquid_pull_to_refresh/liquid_pull_to_refresh.dart';
import 'package:adminapp/classes/customBarChart.dart';
import 'package:dots_indicator/dots_indicator.dart';
class Dashboard extends StatelessWidget {
Dashboard({Key? key}) : super(key: key);
final ControllerDashboard dashboardController =
Get.put(ControllerDashboard());
@override
Widget build(BuildContext context) {
GlobalKey<ScaffoldState> scaffKey = GlobalKey<ScaffoldState>();
PageController pageControllerStatistics = PageController(
initialPage: 0,
keepPage: true,
);
return Scaffold(
key: scaffKey,
backgroundColor: globals.colorMainPageBackground,
body: SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Stack(children: <Widget>[
Container(
height: 130,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 20),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 20),
child: InkWell(
onTap: () => scaffKey.currentState?.openDrawer(),
child: const Icon(
Icons.menu,
size: 30,
color: globals.colorBlueDarkLightAccent,
),
),
),
Padding(
padding: const EdgeInsets.only(left: 18),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: [
RichText(
text: TextSpan(
text: 'Hello, ',
style: const TextStyle(
color: globals.colorBlueDarkText,
fontWeight: FontWeight.w300,
fontSize: 24,
),
children: [
TextSpan(
text:
GetStorage().read('firstname'),
style: const TextStyle(
color: globals.colorBlueDarkText,
fontWeight: FontWeight.bold,
fontSize: 24,
),
)
])),
],
),
SizedBox(
width: 280,
height: 30.0,
child: AutoSizeText(
GetStorage().read('communityname'),
style: const TextStyle(
color: globals.colorBlueDarkText,
fontWeight: FontWeight.w300,
fontSize: 14.0),
maxLines: 1,
),
),
],
),
)
],
),
],
),
),
]),
Stack(
children: <Widget>[
Obx(
() => dashboardController.isLoading.value
? const Padding(
padding: EdgeInsets.only(right: 20),
child: Align(
alignment: Alignment.topRight,
child: Text("Loading"),
),
)
: Container(),
),
],
),
Flexible(
child: LiquidPullToRefresh(
color: globals.colorMainPageBackground,
backgroundColor: globals.colorMainPageBackgroundDark,
springAnimationDurationInMilliseconds: 200,
showChildOpacityTransition: false,
onRefresh: () => dashboardController.syncDashboard(),
child: ListView(
padding: const EdgeInsets.only(left: 5, right: 5),
children: <Widget>[
SizedBox(
height: 215,
child: PageView(
controller: pageControllerStatistics,
children: <Widget>[
Obx(() => CustomBarChart(
chartName: "VISITORS",
chartData: dashboardController.chartVisitorData
.toList())),
Obx(
() => CustomBarChart(
chartName: "VEHICLES",
chartData: dashboardController
.chartVehicleData
.toList()),
),
Obx(
() => CustomBarChart(
chartName: "MAIL",
chartData: dashboardController.chartMailData
.toList()),
),
Obx(
() => CustomBarChart(
chartName: "PACKAGES",
chartData: dashboardController
.chartPackageData
.toList()),
),
],
onPageChanged: (index) => {
dashboardController
.updatePosition(double.parse(index.toString()))
},
),
),
const SizedBox(height: 5),
Obx(
() => DotsIndicator(
dotsCount: dashboardController.totalDots.value,
position:
dashboardController.currentPosition.value),
),
const SizedBox(height: 10),
Obx(() => dashboardController.statusIcons.value),
],
),
),
),
],
),
));
}
}
All of the dashboardController.chartXXXXData variables are .obs and inside the dashboardController.
Any idea? I was thinking that PageView might need to be wrapped in Obi as well, but that does not work.
UPDATE: As suggested, changed to GetBuilder but does not work?
GetBuilder(
init: dashboardController,
builder: (_) => SizedBox(
height: 215,
child: PageView(
controller: pageControllerStatistics,
children: <Widget>[
Obx(() => CustomBarChart(
chartName: "VISITORS",
chartData: dashboardController
.chartVisitorData
.toList())),
Obx(
() => CustomBarChart(
chartName: "VEHICLES",
chartData: dashboardController
.chartVehicleData
.toList()),
),
Obx(
() => CustomBarChart(
chartName: "MAIL",
chartData: dashboardController
.chartMailData
.toList()),
),
Obx(
() => CustomBarChart(
chartName: "PACKAGES",
chartData: dashboardController
.chartPackageData
.toList()),
),
],
onPageChanged: (index) => {
dashboardController.updatePosition(
double.parse(index.toString()))
},
)
Ad changed the controller code to (added update()):
if (response.statusCode == 200) {
// Chart data
var data = json.decode(response.body['d']);
chartVisitorData = data['GraphVisitorsByHoursForToday'];
chartVehicleData = data['GraphVehiclesByHoursForToday'];
chartMailData = data['GraphMailByHoursForToday'];
chartPackageData = data['GraphPackagesByHoursForToday'];
// print(userData);
update();
}
3
Answers
Obx and Getx work only with reactive variable
use Getbuilder instead
and when get data in your controller use update() it should work
Method – 1
You can try to wrap the whole
PageView
inside ObX instead of wrapping each items inside it.Also, if your data type is Rx, then you can ommit the
.toList()
method in the UI.Method – 2
You can try using
GetBuilder
instead of Obx. But in that way, you have to manually call theupdate
method at the end of the function. And you have to wrap your PageView inside theGetBuilder
.You must put your
LiquidPullToRefresh
in Obx, as you are usingdashboardController
at onRefresh.Suggestion:
You should remove all the other
Obx
and go on from here, like if your expected data is not showing then you should put that widget inObx
.