Skip to content

Commit d695376

Browse files
Merge pull request #141 from opencomponents/fix-nested-polling
fix nested polling
2 parents d9b2818 + 911e0e2 commit d695376

File tree

3 files changed

+128
-34
lines changed

3 files changed

+128
-34
lines changed

src/oc-client.js

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -518,41 +518,48 @@ export function createOc(oc) {
518518
let isRendering = dataRendering == "true";
519519
let isRendered = dataRendered == "true";
520520

521-
if (!isRendering && !isRendered) {
522-
logInfo(MESSAGES_RETRIEVING);
523-
setAttribute(dataRenderingAttribute, true);
524-
if (!DISABLE_LOADER) {
525-
component.innerHTML =
526-
'<div class="oc-loading">' + MESSAGES_LOADING_COMPONENT + "</div>";
527-
}
521+
if (isRendered) {
522+
callback();
523+
return;
524+
}
525+
if (isRendering) {
526+
timeout(() => {
527+
oc.renderNestedComponent(component, callback);
528+
}, POLLING_INTERVAL);
529+
return;
530+
}
528531

529-
oc.renderByHref(
530-
{
531-
href: getAttribute("href"),
532-
id: getAttribute("id"),
533-
element: component,
534-
},
535-
(err, data) => {
536-
if (err || !data) {
537-
setAttribute(dataRenderingAttribute, false);
538-
setAttribute(dataRenderedAttribute, false);
539-
setAttribute("data-failed", true);
540-
component.innerHTML = "";
541-
oc.events.fire("oc:failed", {
542-
originalError: err,
543-
data: data,
544-
component,
545-
});
546-
logError(err);
547-
callback();
548-
} else {
549-
processHtml(component, data, callback);
550-
}
551-
},
552-
);
553-
} else {
554-
timeout(callback, POLLING_INTERVAL);
532+
logInfo(MESSAGES_RETRIEVING);
533+
setAttribute(dataRenderingAttribute, true);
534+
if (!DISABLE_LOADER) {
535+
component.innerHTML =
536+
'<div class="oc-loading">' + MESSAGES_LOADING_COMPONENT + "</div>";
555537
}
538+
539+
oc.renderByHref(
540+
{
541+
href: getAttribute("href"),
542+
id: getAttribute("id"),
543+
element: component,
544+
},
545+
(err, data) => {
546+
if (err || !data) {
547+
setAttribute(dataRenderingAttribute, false);
548+
setAttribute(dataRenderedAttribute, false);
549+
setAttribute("data-failed", true);
550+
component.innerHTML = "";
551+
oc.events.fire("oc:failed", {
552+
originalError: err,
553+
data: data,
554+
component,
555+
});
556+
logError(err);
557+
callback();
558+
} else {
559+
processHtml(component, data, callback);
560+
}
561+
},
562+
);
556563
});
557564
};
558565

tests/edgeCases.spec.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ test.describe("oc-client : edge cases", () => {
169169
});
170170

171171
expect(result.callbackCalled).toBe(true);
172-
expect(result.wasDelayed).toBe(true);
172+
expect(result.wasDelayed).toBe(false);
173173
});
174174

175175
test("should handle renderNestedComponent with currently rendering component", async ({
@@ -195,6 +195,11 @@ test.describe("oc-client : edge cases", () => {
195195
wasDelayed: endTime - startTime >= 400,
196196
});
197197
});
198+
199+
setTimeout(() => {
200+
element.setAttribute("data-rendering", "false");
201+
element.setAttribute("data-rendered", "true");
202+
}, 200);
198203
});
199204
});
200205

tests/renderNestedComponent.spec.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,4 +177,86 @@ test.describe("oc-client : renderNestedComponent", () => {
177177
expect(failureResult.failedEvent).toBeDefined();
178178
expect(failureResult.failedEvent.component).toBeDefined();
179179
});
180+
181+
test("should not re-render a component that has already been rendered", async ({
182+
page,
183+
}) => {
184+
const result = await page.evaluate(
185+
(config) => {
186+
return new Promise((resolve) => {
187+
// Create a DOM element
188+
const component = document.createElement("oc-component");
189+
component.setAttribute("href", config.componentHref);
190+
component.setAttribute("data-rendered", "true");
191+
component.innerHTML = "<div>previously rendered content</div>";
192+
let renderByHrefCalls = 0;
193+
// Mock renderByHref
194+
oc.renderByHref = (href, cb) => {
195+
renderByHrefCalls++;
196+
};
197+
198+
// Call the function being tested
199+
oc.renderNestedComponent(component, () => {
200+
resolve({
201+
innerHTML: component.innerHTML,
202+
renderByHrefCalls: renderByHrefCalls,
203+
});
204+
});
205+
});
206+
},
207+
{ componentHref },
208+
);
209+
210+
// Verify the result
211+
expect(result.innerHTML).toContain("previously rendered content");
212+
expect(result.renderByHrefCalls).toBe(0);
213+
});
214+
215+
test("should wait for a component that is already rendering", async ({
216+
page,
217+
}) => {
218+
const result = await page.evaluate(
219+
(config) => {
220+
return new Promise((resolve) => {
221+
const component = document.createElement("oc-component");
222+
component.setAttribute("href", config.componentHref);
223+
component.setAttribute("data-rendering", "true");
224+
document.body.appendChild(component);
225+
226+
let renderByHrefCalls = 0;
227+
oc.renderByHref = (href, cb) => {
228+
renderByHrefCalls++;
229+
cb(null, {
230+
html: "<div>this is the component content</div>",
231+
version: "1.0.0",
232+
name: "my-component",
233+
key: "12345678901234567890",
234+
});
235+
};
236+
237+
// Call the function being tested
238+
oc.renderNestedComponent(component, () => {
239+
const data = {
240+
finalHtml: component.innerHTML,
241+
renderByHrefCalls: renderByHrefCalls,
242+
};
243+
component.remove();
244+
resolve(data);
245+
});
246+
247+
// a bit later, we simulate the end of the rendering
248+
setTimeout(() => {
249+
component.setAttribute("data-rendering", "false");
250+
component.setAttribute("data-rendered", "true");
251+
component.innerHTML = "<div>newly rendered content</div>";
252+
}, 200);
253+
});
254+
},
255+
{ componentHref },
256+
);
257+
258+
// Verify the results
259+
expect(result.finalHtml).toContain("newly rendered content");
260+
expect(result.renderByHrefCalls).toBe(0);
261+
});
180262
});

0 commit comments

Comments
 (0)