diff --git a/src/oc-client.js b/src/oc-client.js
index cc95a5f..1c78ef1 100644
--- a/src/oc-client.js
+++ b/src/oc-client.js
@@ -518,41 +518,48 @@ export function createOc(oc) {
let isRendering = dataRendering == "true";
let isRendered = dataRendered == "true";
- if (!isRendering && !isRendered) {
- logInfo(MESSAGES_RETRIEVING);
- setAttribute(dataRenderingAttribute, true);
- if (!DISABLE_LOADER) {
- component.innerHTML =
- '
' + MESSAGES_LOADING_COMPONENT + "
";
- }
+ if (isRendered) {
+ callback();
+ return;
+ }
+ if (isRendering) {
+ timeout(() => {
+ oc.renderNestedComponent(component, callback);
+ }, POLLING_INTERVAL);
+ return;
+ }
- oc.renderByHref(
- {
- href: getAttribute("href"),
- id: getAttribute("id"),
- element: component,
- },
- (err, data) => {
- if (err || !data) {
- setAttribute(dataRenderingAttribute, false);
- setAttribute(dataRenderedAttribute, false);
- setAttribute("data-failed", true);
- component.innerHTML = "";
- oc.events.fire("oc:failed", {
- originalError: err,
- data: data,
- component,
- });
- logError(err);
- callback();
- } else {
- processHtml(component, data, callback);
- }
- },
- );
- } else {
- timeout(callback, POLLING_INTERVAL);
+ logInfo(MESSAGES_RETRIEVING);
+ setAttribute(dataRenderingAttribute, true);
+ if (!DISABLE_LOADER) {
+ component.innerHTML =
+ '' + MESSAGES_LOADING_COMPONENT + "
";
}
+
+ oc.renderByHref(
+ {
+ href: getAttribute("href"),
+ id: getAttribute("id"),
+ element: component,
+ },
+ (err, data) => {
+ if (err || !data) {
+ setAttribute(dataRenderingAttribute, false);
+ setAttribute(dataRenderedAttribute, false);
+ setAttribute("data-failed", true);
+ component.innerHTML = "";
+ oc.events.fire("oc:failed", {
+ originalError: err,
+ data: data,
+ component,
+ });
+ logError(err);
+ callback();
+ } else {
+ processHtml(component, data, callback);
+ }
+ },
+ );
});
};
diff --git a/tests/edgeCases.spec.js b/tests/edgeCases.spec.js
index 3830d62..f99477a 100644
--- a/tests/edgeCases.spec.js
+++ b/tests/edgeCases.spec.js
@@ -169,7 +169,7 @@ test.describe("oc-client : edge cases", () => {
});
expect(result.callbackCalled).toBe(true);
- expect(result.wasDelayed).toBe(true);
+ expect(result.wasDelayed).toBe(false);
});
test("should handle renderNestedComponent with currently rendering component", async ({
@@ -195,6 +195,11 @@ test.describe("oc-client : edge cases", () => {
wasDelayed: endTime - startTime >= 400,
});
});
+
+ setTimeout(() => {
+ element.setAttribute("data-rendering", "false");
+ element.setAttribute("data-rendered", "true");
+ }, 200);
});
});
diff --git a/tests/renderNestedComponent.spec.js b/tests/renderNestedComponent.spec.js
index 23e70e0..4605d9c 100644
--- a/tests/renderNestedComponent.spec.js
+++ b/tests/renderNestedComponent.spec.js
@@ -177,4 +177,86 @@ test.describe("oc-client : renderNestedComponent", () => {
expect(failureResult.failedEvent).toBeDefined();
expect(failureResult.failedEvent.component).toBeDefined();
});
+
+ test("should not re-render a component that has already been rendered", async ({
+ page,
+ }) => {
+ const result = await page.evaluate(
+ (config) => {
+ return new Promise((resolve) => {
+ // Create a DOM element
+ const component = document.createElement("oc-component");
+ component.setAttribute("href", config.componentHref);
+ component.setAttribute("data-rendered", "true");
+ component.innerHTML = "previously rendered content
";
+ let renderByHrefCalls = 0;
+ // Mock renderByHref
+ oc.renderByHref = (href, cb) => {
+ renderByHrefCalls++;
+ };
+
+ // Call the function being tested
+ oc.renderNestedComponent(component, () => {
+ resolve({
+ innerHTML: component.innerHTML,
+ renderByHrefCalls: renderByHrefCalls,
+ });
+ });
+ });
+ },
+ { componentHref },
+ );
+
+ // Verify the result
+ expect(result.innerHTML).toContain("previously rendered content");
+ expect(result.renderByHrefCalls).toBe(0);
+ });
+
+ test("should wait for a component that is already rendering", async ({
+ page,
+ }) => {
+ const result = await page.evaluate(
+ (config) => {
+ return new Promise((resolve) => {
+ const component = document.createElement("oc-component");
+ component.setAttribute("href", config.componentHref);
+ component.setAttribute("data-rendering", "true");
+ document.body.appendChild(component);
+
+ let renderByHrefCalls = 0;
+ oc.renderByHref = (href, cb) => {
+ renderByHrefCalls++;
+ cb(null, {
+ html: "this is the component content
",
+ version: "1.0.0",
+ name: "my-component",
+ key: "12345678901234567890",
+ });
+ };
+
+ // Call the function being tested
+ oc.renderNestedComponent(component, () => {
+ const data = {
+ finalHtml: component.innerHTML,
+ renderByHrefCalls: renderByHrefCalls,
+ };
+ component.remove();
+ resolve(data);
+ });
+
+ // a bit later, we simulate the end of the rendering
+ setTimeout(() => {
+ component.setAttribute("data-rendering", "false");
+ component.setAttribute("data-rendered", "true");
+ component.innerHTML = "newly rendered content
";
+ }, 200);
+ });
+ },
+ { componentHref },
+ );
+
+ // Verify the results
+ expect(result.finalHtml).toContain("newly rendered content");
+ expect(result.renderByHrefCalls).toBe(0);
+ });
});