Skip to content

Commit aa81251

Browse files
author
Christian Budde Christensen
committed
feat: Cache parsed data
1 parent 0953e94 commit aa81251

File tree

2 files changed

+96
-4
lines changed

2 files changed

+96
-4
lines changed

packages/graphql/lib/src/core/query_result.dart

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,14 @@ final _eagerSources = {
4343
class QueryResult<TParsed extends Object?> {
4444
@protected
4545
QueryResult.internal({
46-
this.data,
46+
Map<String, dynamic>? data,
4747
this.exception,
4848
this.context = const Context(),
4949
required this.parserFn,
5050
required this.source,
51-
}) : timestamp = DateTime.now();
51+
}) : timestamp = DateTime.now() {
52+
_data = data;
53+
}
5254

5355
factory QueryResult({
5456
required BaseOptions<TParsed> options,
@@ -99,7 +101,17 @@ class QueryResult<TParsed extends Object?> {
99101
QueryResultSource? source;
100102

101103
/// Response data
102-
Map<String, dynamic>? data;
104+
Map<String, dynamic>? get data {
105+
return _data;
106+
}
107+
108+
set data(Map<String, dynamic>? data) {
109+
_data = data;
110+
_cachedParsedData = null;
111+
}
112+
113+
Map<String, dynamic>? _data;
114+
TParsed? _cachedParsedData;
103115

104116
/// Response context. Defaults to an empty `Context()`
105117
Context context;
@@ -137,11 +149,15 @@ class QueryResult<TParsed extends Object?> {
137149
TParsed? get parsedData {
138150
final data = this.data;
139151
final parserFn = this.parserFn;
152+
final cachedParsedData = _cachedParsedData;
140153

141154
if (data == null) {
142155
return null;
143156
}
144-
return parserFn(data);
157+
if (cachedParsedData != null) {
158+
return cachedParsedData;
159+
}
160+
return _cachedParsedData = parserFn(data);
145161
}
146162

147163
@override
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import 'package:gql/language.dart';
2+
import 'package:graphql/client.dart';
3+
import 'package:test/test.dart';
4+
5+
void main() {
6+
group('Query result', () {
7+
test('data parsing should work with null data', () {
8+
int runTimes = 0;
9+
final result = QueryResult<String?>(
10+
options: QueryOptions(
11+
document: parseString('query { bar }'),
12+
parserFn: (data) {
13+
runTimes++;
14+
return data['bar'] as String?;
15+
},
16+
),
17+
source: QueryResultSource.network,
18+
data: null,
19+
);
20+
expect(result.parsedData, equals(null));
21+
expect(runTimes, equals(0));
22+
});
23+
test('data parsing should work with data', () {
24+
int runTimes = 0;
25+
final bar = "Bar";
26+
final result = QueryResult<String?>(
27+
options: QueryOptions(
28+
document: parseString('query { bar }'),
29+
parserFn: (data) {
30+
runTimes++;
31+
return data['bar'] as String?;
32+
},
33+
),
34+
source: QueryResultSource.network,
35+
data: {"bar": bar},
36+
);
37+
expect(result.parsedData, equals(bar));
38+
expect(result.parsedData, equals(bar));
39+
expect(runTimes, equals(1));
40+
});
41+
test('data parsing should work with data', () {
42+
final bar = "Bar";
43+
final result = QueryResult<String?>(
44+
options: QueryOptions(
45+
document: parseString('query { bar }'),
46+
parserFn: (data) {
47+
return data['bar'] as String?;
48+
},
49+
),
50+
source: QueryResultSource.network,
51+
data: {"bar": bar},
52+
);
53+
expect(result.data, equals({"bar": bar}));
54+
});
55+
test('updating data should clear parsed data', () {
56+
int runTimes = 0;
57+
final bar = "Bar";
58+
final result = QueryResult<String?>(
59+
options: QueryOptions(
60+
document: parseString('query { bar }'),
61+
parserFn: (data) {
62+
runTimes++;
63+
return data['bar'] as String?;
64+
},
65+
),
66+
source: QueryResultSource.network,
67+
data: {"bar": bar},
68+
);
69+
expect(result.parsedData, equals(bar));
70+
expect(runTimes, equals(1));
71+
result.data = {"bar": bar};
72+
expect(result.parsedData, equals(bar));
73+
expect(runTimes, equals(2));
74+
});
75+
});
76+
}

0 commit comments

Comments
 (0)