Skip to content

Commit 4220724

Browse files
authored
fix: fixed how the web chat script is loaded to avoid duplicates (#19)
[skip ci]
1 parent 4c10a9d commit 4220724

File tree

3 files changed

+20
-49
lines changed

3 files changed

+20
-49
lines changed

src/WebChatContainer.tsx

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,6 @@ const DEFAULT_BASE_URL = 'https://web-chat.global.assistant.watson.appdomain.clo
2424
// Indicate if debugging is enabled.
2525
let debug = false;
2626

27-
// The first time the container is mounted, we need to load the javascript for web chat from the CDN. This should
28-
// only happen once. This Promise is used to ensure that and to allow anyone to wait for that script to be loaded.
29-
let loadWebChatScriptPromise: Promise<unknown>;
30-
31-
// The URL that was used to load the web chat javascript. This is to ensure we don't attempt to load different scripts.
32-
let loadedWebChatURL: string;
33-
3427
interface ManagedWebChat {
3528
/**
3629
* The config for the web chat that is loaded.
@@ -256,34 +249,28 @@ async function ensureWebChatScript(webChatConfig: WebChatConfig, hostURL: string
256249
webChatConfig.clientVersion || 'latest'
257250
}/WatsonAssistantChatEntry.js`;
258251

252+
const loadedWebChatURL = (window as any).wacWebChatContainerScriptURL;
259253
if (loadedWebChatURL && loadedWebChatURL !== scriptURL) {
260-
const message =
261-
'Web chat has already been loaded using a different URL. This component does not support loading web chat' +
262-
' using multiple URLs including different versions of web chat.';
254+
const message = `Web chat has already been loaded using a different URL (${loadedWebChatURL}). This component does not support loading web chat using multiple URLs including different versions of web chat. The current code attempted to load from ${scriptURL}.`;
263255
logger(null, message);
264256
}
265-
loadedWebChatURL = scriptURL;
266257

267-
if (!loadWebChatScriptPromise) {
268-
loadWebChatScriptPromise = loadWebChatScript(scriptURL);
258+
// Check to see if we already have a Promise for loading this script. We're using a window property to cover the
259+
// case where multiple library instances are being used that can't necessarily share module state.
260+
if (!(window as any).wacWebChatContainerScriptPromise) {
261+
logger(null, `Loading the web chat javascript from ${scriptURL}.`);
262+
263+
(window as any).wacWebChatContainerScriptPromise = new Promise<void>((resolve, reject) => {
264+
const scriptElement = document.createElement('script');
265+
scriptElement.onload = () => resolve();
266+
scriptElement.onerror = () => reject();
267+
scriptElement.src = scriptURL;
268+
document.head.appendChild(scriptElement);
269+
(window as any).wacWebChatContainerScriptURL = scriptURL;
270+
});
269271
}
270-
await loadWebChatScriptPromise;
271-
}
272272

273-
/**
274-
* Loads the web chat javascript from the CDN.
275-
*/
276-
function loadWebChatScript(url: string): Promise<void> {
277-
logger(null, `Loading the web chat javascript from ${url}.`);
278-
279-
return new Promise((resolve, reject) => {
280-
const scriptElement = document.createElement('script');
281-
scriptElement.setAttribute('id', 'with-web-chat');
282-
scriptElement.onload = () => resolve();
283-
scriptElement.onerror = () => reject();
284-
scriptElement.src = url;
285-
document.head.appendChild(scriptElement);
286-
});
273+
return (window as any).wacWebChatContainerScriptPromise;
287274
}
288275

289-
export { setEnableDebug, WebChatContainer, WebChatContainerProps };
276+
export { setEnableDebug, WebChatContainer, WebChatContainerProps, ensureWebChatScript };

src/__tests__/WebChatContainer.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe('WebChatContainer', () => {
4545

4646
await waitForWebChat(findAllByPlaceholderText);
4747
// This second configuration should display the close and restart button.
48-
await waitForFind('End conversation and close the chat window', findAllByLabelText);
48+
await waitForFind('End chat and close the window', findAllByLabelText);
4949
});
5050

5151
it('tests that the component renders correctly when mounted, unmounted and re-mounted', async () => {

src/withWebChat.tsx

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import React from 'react';
1919
import { WithWebChatConfig, OriginalProps, ForwardedRefProps, WithWebChatProps } from './types/WithWebChatTypes';
2020
import { WebChatConfig } from './types/WebChatConfig';
2121
import { WebChatInstance } from './types/WebChatInstance';
22+
import { ensureWebChatScript } from './WebChatContainer';
2223

2324
const DEFAULT_BASE_URL = 'https://web-chat.global.assistant.watson.appdomain.cloud';
2425

@@ -140,7 +141,7 @@ function withWebChat(passedConfig: WithWebChatConfig = {}) {
140141
// If the script tag for web chat has not been injected on the page, do so now.
141142
if (!loadWebChatScriptPromise) {
142143
logger('appending web chat scripts to body');
143-
loadWebChatScriptPromise = loadWebChatScript(webChatConfig, config.baseUrl);
144+
loadWebChatScriptPromise = ensureWebChatScript(webChatConfig, config.baseUrl);
144145
}
145146

146147
loadWebChatScriptPromise
@@ -256,21 +257,4 @@ class Deferred<T> {
256257
}
257258
}
258259

259-
// Inject WatsonAssistantChatEntry.js on the page and return a promise that resolves successfully onload.
260-
function loadWebChatScript(webChatConfig: WebChatConfig, baseUrl: string): Promise<void> {
261-
const src = `${baseUrl.replace(/\/$/, '')}/versions/${
262-
webChatConfig.clientVersion || 'latest'
263-
}/WatsonAssistantChatEntry.js`;
264-
265-
return new Promise((resolve, reject) => {
266-
const scriptElement = document.createElement('script');
267-
scriptElement.setAttribute('id', 'with-web-chat');
268-
scriptElement.setAttribute('async', 'true');
269-
scriptElement.onload = () => resolve();
270-
scriptElement.onerror = () => reject();
271-
scriptElement.src = src;
272-
document.head.appendChild(scriptElement);
273-
});
274-
}
275-
276260
export { withWebChat };

0 commit comments

Comments
 (0)