Skip to content

Commit cc2f0d6

Browse files
committed
Merge branch 'fix/updated-document-subscriptions' into 'develop'
Fixed document subscriptions caused by the update to React 18 and Amplify's... See merge request genaiic-reusable-assets/engagement-artifacts/genaiic-idp-accelerator!368
2 parents 78a1c69 + 70d7ec7 commit cc2f0d6

File tree

1 file changed

+60
-21
lines changed

1 file changed

+60
-21
lines changed

src/ui/src/hooks/use-graphql-api.js

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
3-
import { useEffect, useState } from 'react';
3+
import { useEffect, useState, useCallback, useRef } from 'react';
44
import { generateClient } from 'aws-amplify/api';
55
import { ConsoleLogger } from 'aws-amplify/utils';
66

@@ -24,21 +24,26 @@ const useGraphQlApi = ({ initialPeriodsToLoad = DOCUMENT_LIST_SHARDS_PER_DAY * 2
2424
const [documents, setDocuments] = useState([]);
2525
const { setErrorMessage } = useAppContext();
2626

27-
const setDocumentsDeduped = (documentValues) => {
27+
const subscriptionsRef = useRef({ onCreate: null, onUpdate: null });
28+
29+
const setDocumentsDeduped = useCallback((documentValues) => {
30+
logger.debug('setDocumentsDeduped called with:', documentValues);
2831
setDocuments((currentDocuments) => {
2932
const documentValuesdocumentIds = documentValues.map((c) => c.ObjectKey);
30-
return [
33+
const updatedDocuments = [
3134
...currentDocuments.filter((c) => !documentValuesdocumentIds.includes(c.ObjectKey)),
3235
...documentValues.map((document) => ({
3336
...document,
3437
ListPK: document.ListPK || currentDocuments.find((c) => c.ObjectKey === document.ObjectKey)?.ListPK,
3538
ListSK: document.ListSK || currentDocuments.find((c) => c.ObjectKey === document.ObjectKey)?.ListSK,
3639
})),
3740
];
41+
logger.debug('Documents state updated, new count:', updatedDocuments.length);
42+
return updatedDocuments;
3843
});
39-
};
44+
}, []);
4045

41-
const getDocumentDetailsFromIds = async (objectKeys) => {
46+
const getDocumentDetailsFromIds = useCallback(async (objectKeys) => {
4247
// prettier-ignore
4348
logger.debug('getDocumentDetailsFromIds', objectKeys);
4449
const getDocumentPromises = objectKeys.map((objectKey) =>
@@ -55,46 +60,80 @@ const useGraphQlApi = ({ initialPeriodsToLoad = DOCUMENT_LIST_SHARDS_PER_DAY * 2
5560
.map((r) => r.value?.data?.getDocument);
5661

5762
return documentValues;
58-
};
63+
}, [setErrorMessage]);
5964

6065
useEffect(() => {
66+
if (subscriptionsRef.current.onCreate) {
67+
logger.debug('onCreateDocument subscription already exists, skipping');
68+
return;
69+
}
70+
6171
logger.debug('onCreateDocument subscription');
6272
const subscription = client.graphql({ query: onCreateDocument }).subscribe({
63-
next: async ({ provider, value }) => {
64-
logger.debug('document list subscription update', { provider, value });
65-
const objectKey = value?.data?.onCreateDocument.ObjectKey || '';
73+
next: async (subscriptionData) => {
74+
logger.debug('document list subscription update', subscriptionData);
75+
const data = subscriptionData?.data;
76+
const objectKey = data?.onCreateDocument?.ObjectKey || '';
6677
if (objectKey) {
67-
const documentValues = await getDocumentDetailsFromIds([objectKey]);
68-
setDocumentsDeduped(documentValues);
78+
try {
79+
const documentValues = await getDocumentDetailsFromIds([objectKey]);
80+
if (documentValues && documentValues.length > 0) {
81+
setDocumentsDeduped(documentValues);
82+
}
83+
} catch (error) {
84+
logger.error('Error processing onCreateDocument subscription:', error);
85+
}
6986
}
7087
},
7188
error: (error) => {
72-
logger.error(error);
89+
logger.error('onCreateDocument subscription error:', error);
7390
setErrorMessage('document list network subscription failed - please reload the page');
7491
},
7592
});
7693

77-
return () => subscription.unsubscribe();
78-
}, []);
94+
subscriptionsRef.current.onCreate = subscription;
95+
96+
return () => {
97+
logger.debug('onCreateDocument subscription cleanup');
98+
if (subscriptionsRef.current.onCreate) {
99+
subscriptionsRef.current.onCreate.unsubscribe();
100+
subscriptionsRef.current.onCreate = null;
101+
}
102+
};
103+
}, [getDocumentDetailsFromIds, setDocumentsDeduped, setErrorMessage]);
79104

80105
useEffect(() => {
81-
logger.debug('onUpdateDocument subscription');
106+
if (subscriptionsRef.current.onUpdate) {
107+
logger.debug('onUpdateDocument subscription already exists, skipping');
108+
return;
109+
}
110+
111+
logger.debug('onUpdateDocument subscription setup');
82112
const subscription = client.graphql({ query: onUpdateDocument }).subscribe({
83-
next: async ({ provider, value }) => {
84-
logger.debug('document update', { provider, value });
85-
const documentUpdateEvent = value?.data?.onUpdateDocument;
113+
next: async (subscriptionData) => {
114+
logger.debug('document update subscription received', subscriptionData);
115+
const data = subscriptionData?.data;
116+
const documentUpdateEvent = data?.onUpdateDocument;
86117
if (documentUpdateEvent?.ObjectKey) {
87118
setDocumentsDeduped([documentUpdateEvent]);
88119
}
89120
},
90121
error: (error) => {
91-
logger.error(error);
122+
logger.error('onUpdateDocument subscription error:', error);
92123
setErrorMessage('document update network request failed - please reload the page');
93124
},
94125
});
95126

96-
return () => subscription.unsubscribe();
97-
}, []);
127+
subscriptionsRef.current.onUpdate = subscription;
128+
129+
return () => {
130+
logger.debug('onUpdateDocument subscription cleanup');
131+
if (subscriptionsRef.current.onUpdate) {
132+
subscriptionsRef.current.onUpdate.unsubscribe();
133+
subscriptionsRef.current.onUpdate = null;
134+
}
135+
};
136+
}, [setDocumentsDeduped, setErrorMessage, getDocumentDetailsFromIds]);
98137

99138
const listDocumentIdsByDateShards = async ({ date, shards }) => {
100139
const listDocumentsDateShardPromises = shards.map((i) => {

0 commit comments

Comments
 (0)