Skip to main content

Jobs API

All this time, we've been directly supplying queryKey, queryFn etc to QueryBuilder and so on. But this might looks repetetive or might break the rules of DRY (Don't Repeat Yourself). So to tackle this issue Fl-Query has an alternate API to create queries/infinite queries/mutations.

Jobs are nothing but a collection of arguments of *Builders. It is just a more declarative way to create queries/infinite queries/mutations.

Query Job

A QueryJob consists of same arguments as QueryBuilder

final job = QueryJob<List<Todo>, dynamic, HttpApi>(
queryKey: "todos",
task: (api) => api.getTodos(),
);

You might notice the third type argument HttpApi. That's the new ArgsType. Because QueryJob is isolated from widget tree and outside APIs are not accessible from there, you've to manually pass anything you need to the task function. In this case, we need an instance of HttpApi to call getTodos().

QueryBuilder.withJob and useQueryJob

QueryBuilder.withJob is a static method that takes a QueryJob and returns a QueryBuilder. It also accepts event callbacks such as onError and onData. Also a special argument called args which is passed to the task function.

Similarly, we have a useQueryJob if you're using flutter_hooks

QueryBuilder.withJob(
job: job, // QueryJob we created earlier
args: httpApi,
onError: (error) => print(error),
onData: (data) => print(data),
builder: /* ... */,
);

InfiniteQuery Job

Just like QueryJob, InfiniteQueryJob is the collection of arguments that is passed to InfiniteQueryBuilder or useInfiniteQuery

final job = InfiniteQueryBuilder<PagedProducts, ClientException, int, HttpApi>(
queryKey: "products",
task: (page, api) => api.getProductsPaginated(page),
nextPage: (lastPage, lastPageData) {
/// returning [null] will set [hasNextPage] to [false]
if (lastPageData.products.length < 10) return null;
return lastPage + 1;
},
initialPage: 0,
);

InfiniteQueryBuilder.withJob and useInfiniteQueryJob

Just like QueryBuilder.withJob, InfiniteQueryBuilder.withJob is a static method that takes a InfiniteQueryJob and returns a InfiniteQueryBuilder. It also accepts event callbacks such as onError and onData. Also a special argument called args which is passed to the task function.

Simiarly, we have a useInfiniteQueryJob if you're using flutter_hooks

InfiniteQueryBuilder.withJob(
job: job, // InfiniteQueryJob we created earlier
args: httpApi,
onError: (error) => print(error),
onData: (data) => print(data),
builder: /* ... */,
);

Mutation Job

For mutations we've MutationJob it is similar to QueryJob but has mutationKey instead of queryKey

final job = MutationJob<Todo, dynamic, Todo, void, HttpApi>(
mutationKey: "create-todo",
task: (variables, api) => api.createTodo(),
);
info

MutationJob has both variables and args which can be confusing. But use variables for passing data that are supposed to be sent, that means data that can change on next mutation.

Use args for passing anything that is not supposed to change, like an API instance, authentication info or a config etc.

MutationBuilder.withJob and useMutationJob

Just like QueryBuilder.withJob, MutationBuilder.withJob is a static method that takes a MutationJob and returns a MutationBuilder. It also accepts event callbacks such as onMutate, onError and onData. Also a special argument called args which is passed to the task function.

Simiarly, we have a useMutationJob if you're using flutter_hooks

MutationBuilder.withJob(
job: job, // MutationJob we created earlier
args: httpApi,
onError: (error) => print(error),
onData: (data) => print(data),
builder: /* ... */,
);

Dynamic Jobs

Every job has .withVariableKey static that allows creating queries/mutations with changing data on the fly. It returns a function that accepts a variable key (String). Which will create a new instance of the job with the new variable key.

Here's the example usage for Query:

final job = QueryJob.withVariableKey<List<Todo>, dynamic, HttpApi>(
baseQueryKey: "todos/", // the variable key will be appended to this
task: (variableKey, api) => api.getTodo(variableKey),
);

// later in the widget tree
QueryBuilder.withJob(
job: job(todoId),
args: httpApi,
builder: /* ... */,
);

Everything is just as same as for Mutation and InfiniteQuery..