Skip to main content

Dynamic Queries

All this time we've using queries by defining a Query Key in the QueryJob. But what if your widget needs to fetch data from of a dynamic id that is only known at runtime? This is where QueryJob.withVariableKey comes to play. It allows you to define query-key at runtime. It makes a query dynamic

final queryVariableKeyJob =
QueryJob.withVariableKey<String, void>(
prevQueryKey: "variable-query",
task: (queryKey, externalData) {
return Future.delayed(
const Duration(milliseconds: 500),
() => "QueryKey:${getVariable(queryKey)}",
);
},
);

Optionally, we can provide a prevQueryKey to make the QueryJob distinguishable from other dynamic Queries or just to keep them in a group. If you use prevQueryKey, you can use getVariable to extract the value of the variable from the queryKey.

warning

Don't use externalData to make a query dynamic. Using externalData & refetchOnExternalDataChange: true, you may be able to achieve similar result but it'll replace the previously fetched data with the new data instead of creating a separate Query instance for the new variable-query-key & it's data

Now, let's use the Job with a QueryBuilder inside an actual widget:

class ExampleState extends State<Example>{
late double id;

void initState() {
super.initState();
id = Random().nextDouble() * 200;
}


Widget build(BuildContext context) {
return QueryBuilder<String, void>(
job: queryVariableKeyJob(id.toString()),
externalData: null,
builder: (context, query) {
if (!query.hasData) {
return const CircularProgressIndicator();
}
return Row(
children: [
Text("Query Result: ${query.data}"),
ElevatedButton(
child: const Text("New Id"),
onPressed: () {
setState(() {
id = Random().nextDouble() * 200;
});
},
),
],
);
},
);
}
}

Here, everything is same except to pass the variable-query-key to the dynamic Query you'll have to invoke the defined job (in this case it's queryVariableKeyJob) & pass the variable-query-key as an argument.