Open dmitrysdm opened 2 years ago
I reread Apollo documentation, subscribeToMore - it how they solve part of this problem (this function used in my example)
I think i found solution on riverpod main page ( it is contain example for combine two providers, exacly with switch case code example :) ), i think architectural it is correct.
I left this issue open, just for feedback and other opinion, to be sure, that found way is correct.
PRs are always welcome
I still have not good working solution, and it related (as i think) with issue: #1278 How to dispose subscription request?
Even through riverpod provider, i can't understand how to handle unsubscribe (dispose) after widget was unmount.
Now my schema is follow:
1) GraphQLClient provider (return _client) 2) Repository provider (contain all query mutations and subscriptions, get graphql client from "GraphQLClient provider" )
class UserRepository implements IUserRepository {
final GraphQLClient client;
UserRepository({
required this.client,
});
@override
Future<List<User>> getAllUsers() async {
final QueryOptions options = QueryOptions(
document: gql(
r'''
query {
getAllUsers {
id
name
description
}
}
''',
),
);
final QueryResult result = await client.query(options);
final List<dynamic> json = result.data!['getAllUsers'] as List<dynamic>;
return json.map<User>((element) => User.fromJson(element)).toList();
}
@override
Stream<UserUpdated> userUpdated() async* {
final SubscriptionOptions options = SubscriptionOptions(
document: gql(
r'''
subscription {
userUpdated {
mutation
user {
id
name
description
}
}
}
''',
),
);
await for (final result in client.subscribe(options)) {
yield UserUpdated.fromJson(result.data!['userUpdated']);
}
}
}
3) StateNotifier provider (get repository from "Repository provider") contein follow code for combine queries and subscriptions:
Future<void> initUpdatesUser() async {
state = await repository.getAllUsers();
var update = repository.userUpdated();
update.listen((update) {
switch (update.mutation) {
case 'addUser':
state = ...;
break;
case 'updateUser':
state = ...;
break;
case 'removeUser':
state = ...;
break;
}
});
}
4) UI part (get users list and listen for changes from "StateNotifier provider")
Now it's almost work, on first start all good, but i have a problems when i change route (when my widget unmount/remount), i think the reason for this - is widget/provider dispose handle, because unsubscribe is not exist on "Repository provider" level :(
I have an idea with implementation of an additional provider for updates (I assume that this provider with own dispose, also will do dispose for subscriptions), but it still not tested.
I have found solution via riverpod (subscriptions dispose was not fixed, but now another errors are epsen), it is sufficient for me.
Good morning, i'm looking for example, that allow combine query and subscription in one widget (one local state). Processing one common local state is more difficult part for understanding :(
What i want is - a large table with many users, who edit it at the same time.
As result, according Dumb and Smart Components model, i need follow:
Smart Component contain:
Dumb Component contain:
on React, based on hooks implementation looks like:
switch case by tableRowUpdated.mutation i use for minimize needed resources, and instead of return whole table from server, returns only table row, that updated on client side according mutation
I need for example how to combine query and subscription in one widget at same time, for processing one widget local state.
At same time i am trying to use global state via riverpod provider, and after example with local state processing this, i hope, it will be the same.