Async data fetch without using FutureBuilder

Hi, I've been using the following exmaple (How to populate Flutter DataTablewith JSON API) in order to fetch paginated data from an API that I made, the problem is that when using future builder the state of the grid rebuilds for every snapshot given from the future builder. This specific case affects me because I cannot use chackbox columns without them deselecting themselves due to the rebuild of the widget. Here I attach a fragment of my code:

FutureBuilder(
future: datosEventos(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
return snapshot.hasData
? SizedBox(
height: 500,
width: MediaQuery.of(context).size.width / 2,
child: Stack(
children: [Column(
children: [
Checkbox(
value: mostrar,
onChanged: (v) {
setState(() {
mostrar = v ?? false;
});
}
),
Card(
child: SfDataGrid(
rowsPerPage: _filasPorPagina,
columnWidthMode: ColumnWidthMode.fill,
columnResizeMode: ColumnResizeMode.onResize,
source: dataSource,
controller: controller,
showCheckboxColumn: mostrar,
selectionMode: SelectionMode.multiple,
columns: [
GridColumn(
columnName: 'Folio',
//width: ,
label: Container(
padding: const EdgeInsets.all(8),
alignment: Alignment.center,
child: const Text(
'Folio',
overflow: TextOverflow.clip,
softWrap: true,
),
),
),
GridColumn(
columnName: 'Incidencia',
//width: ,
label: Container(
padding: const EdgeInsets.all(8),
alignment: Alignment.centerLeft,
child: const Text(
'Incidencia',
overflow: TextOverflow.clip,
softWrap: true,
),
),
),
GridColumn(
columnName: 'Direccion',
//width: ,
label: Container(
padding: const EdgeInsets.all(8),
alignment: Alignment.centerLeft,
child: const Text(
'Direccion',
overflow: TextOverflow.clip,
softWrap: true,
),
),
),
],
),
),
Container(
height: 75,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface.withOpacity(0.12),
border: Border(
top: BorderSide(
width: .5,
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.12)
),
bottom: BorderSide.none,
left: BorderSide.none,
right: BorderSide.none
)
),
child: Align(
alignment: Alignment.center,
child: SfDataPagerTheme(
data: SfDataPagerThemeData(
brightness: Theme.of(context).brightness,
selectedItemColor: Colors.blue,
),
child: SfDataPager(
visibleItemsCount: 3,
onPageNavigationStart: (index) {
setState(() {
cargando = true;
});
},
onPageNavigationEnd: (index) {
setState(() {
cargando = false;
});
},
delegate: dataSource,
availableRowsPerPage: const <int>[20, 40, 80],
pageCount: snapshot.data.filas / _filasPorPagina,
onRowsPerPageChanged: (int? rowsPerPage) {
setState(() {
_filasPorPagina = rowsPerPage!;
});
},
direction: Axis.horizontal,
),
),
),
)
],
),
cargando ? Container(
color: Colors.black12,
height: 305,
child: const Align(
alignment: Alignment.center,
child: Card(
child: CircularProgressIndicator(
strokeWidth: 3,
),
)
)
) : const SizedBox()]
),
)
: const Center(child: CircularProgressIndicator());
},
)

3 Replies 1 reply marked as answer

TP Tamilarasan Paranthaman Syncfusion Team February 10, 2022 02:06 PM UTC

Hi Alejandro, 
You can achieve the requirement by maintaining the selected DataGrid row with the page index in the local collection. Add the onPageNavigationStart callback, add the selected rows in the DataGrid controller to a local collection. In the onPageNavigationEnd callback, map selected rows in the collection to the DataGrid controller's selected rows property based on the page index. We have prepared a sample for that. Please check the following sample and code snippet. 
 
Code Snippet:  
List<DataGridRow> selectedRows = []; 
Map<String, List<DataGridRow>> selectedRowsCollection = {}; 
 
SfDataPager( 
controller: _dataPagerController, 
onPageNavigationStart: (int pageIndex) { 
selectedRows = _dataGridController.selectedRows; 
selectedRowsCollection[_dataPagerController 
.selectedPageIndex 
.toString()] = selectedRows.toList(); 
}, 
onPageNavigationEnd: (int pageIndex) { 
if (selectedRowsCollection 
.containsKey('$pageIndex') && 
selectedRowsCollection['$pageIndex'] != 
null && 
selectedRowsCollection['$pageIndex']! 
.isNotEmpty) { 
_dataGridController.selectedRows = 
selectedRowsCollection['$pageIndex']!; 
} 
}, 
delegate: jsonDataGridSource, 
pageCount: _filasPorPagina.toDouble(), 
direction: Axis.horizontal, 
), 
 
 
 
We hope this helps. If we misunderstood anything, please modify the above sample based on your requirement. It will be helpful for us to check on it and provide you with the solution at the earliest. 
 
Regards, 
Tamilarasan P 


Marked as answer

AL Alejandro replied to Tamilarasan Paranthaman February 10, 2022 07:26 PM UTC

Many thanks, this works for keeping the selected rows



TP Tamilarasan Paranthaman Syncfusion Team February 11, 2022 04:50 AM UTC

Hi Alejandro, 
 
We are glad that the provided response meets your requirement. Please let us know if you need further assistance. As always, we are happy to help you out
 
Regards, 
Tamilarasan 


Loader.
Up arrow icon