Skip to content

Commit f9c09e5

Browse files
Update after review
1 parent c3c5439 commit f9c09e5

File tree

7 files changed

+187
-177
lines changed

7 files changed

+187
-177
lines changed

Angular/src/app/app.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
</dx-pagination>
1919
<div id="cards">
2020
<ng-container *ngFor="let color of visibleCards">
21-
<img [src]="color.image" [alt]="color.name" />
21+
<img [src]="color.image.bare" [alt]="color.name.value" />
2222
</ng-container>
2323
</div>
2424
</div>

Angular/src/app/app.component.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
#container {
2+
margin: 50px;
3+
width: 90vh;
4+
}
5+
16
#cards {
27
display: flex;
38
justify-content: center;

Angular/src/app/app.component.ts

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable no-console */
21
import { Component } from '@angular/core';
32
import { firstValueFrom } from 'rxjs';
43
import { ColorService, Color } from './app.service';
@@ -14,7 +13,9 @@ export class AppComponent {
1413

1514
total = 100;
1615

17-
colors: Color[] = [];
16+
colors: Map<string, Color> = new Map();
17+
18+
hexCodes: string[] = [];
1819

1920
visibleCards: Color[] = [];
2021

@@ -25,44 +26,55 @@ export class AppComponent {
2526
constructor(private readonly colorService: ColorService) {}
2627

2728
ngOnInit(): void {
28-
// eslint-disable-next-line no-void
29-
void this.generateColors();
29+
this.generateHexCodes();
30+
this.updateVisibleCards();
3031
}
3132

32-
async generateColors(): Promise<void> {
33-
this.loadPanelVisible = true;
34-
const promises: Promise<any>[] = [];
35-
33+
generateHexCodes(): void {
3634
for (let i = 0; i < this.total; i++) {
37-
const hex = this.colorService.getRandomPastelColor();
38-
const promise = firstValueFrom(
39-
this.colorService.fetchColorData(hex),
40-
).then((data) => ({ name: data.name.value, image: data.image.bare }));
41-
42-
promises.push(promise);
35+
this.hexCodes.push(this.colorService.getRandomPastelColor());
4336
}
37+
}
38+
39+
async fetchColorsForPage(): Promise<void> {
40+
const startIndex = (this.pageIndex - 1) * this.pageSize;
41+
const endIndex = this.pageIndex * this.pageSize;
42+
const hexSubset = this.hexCodes.slice(startIndex, endIndex);
4443

44+
const promises: Promise<Color>[] = hexSubset.map((hex) => {
45+
if (this.colors.has(hex)) {
46+
return Promise.resolve(this.colors.get(hex)!);
47+
} else {
48+
return firstValueFrom(this.colorService.fetchColorData(hex)).then((data) => {
49+
const colorData: Color = data;
50+
this.colors.set(hex, colorData);
51+
return colorData;
52+
});
53+
}
54+
});
55+
56+
this.loadPanelVisible = true;
4557
try {
46-
this.colors = await Promise.all(promises);
58+
const fetchedColors = await Promise.all(promises);
59+
this.visibleCards = fetchedColors;
4760
} catch (error) {
48-
console.error('Error generating colors:', error);
61+
console.error('Error fetching colors:', error);
4962
} finally {
50-
this.setVisibleCards();
5163
this.loadPanelVisible = false;
5264
}
5365
}
5466

5567
onPageIndexChange(val: number): void {
5668
this.pageIndex = val;
57-
this.setVisibleCards();
69+
void this.fetchColorsForPage();
5870
}
5971

6072
onPageSizeChange(val: number): void {
6173
this.pageSize = val;
62-
this.setVisibleCards();
74+
void this.fetchColorsForPage();
6375
}
6476

65-
setVisibleCards(): void {
66-
this.visibleCards = this.colors.slice((this.pageIndex - 1) * this.pageSize, this.pageIndex * this.pageSize);
77+
updateVisibleCards(): void {
78+
void this.fetchColorsForPage();
6779
}
6880
}

React/src/App.tsx

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,62 +17,62 @@ interface Color {
1717
}
1818

1919
function App(): JSX.Element {
20-
const isMounted = useRef(false);
2120
const [loadPanelVisible, setLoadPanelVisible] = useState<boolean>(false);
2221
const [pageSize, setPageSize] = useState<number>(5);
2322
const [pageIndex, setPageIndex] = useState<number>(3);
24-
const [colors, setColors] = useState<Color[]>([]);
2523
const [visibleCards, setVisibleCards] = useState<Color[]>([]);
2624

27-
const getVisibleCards = useCallback((currentPageIndex: number, currentPageSize: number): void => {
28-
const startIndex = (currentPageIndex - 1) * currentPageSize;
29-
const endIndex = startIndex + currentPageSize;
30-
const pageColors = colors.slice(startIndex, endIndex);
31-
setVisibleCards(pageColors);
32-
setLoadPanelVisible(false);
33-
}, [colors, visibleCards]);
25+
const hexCodes = useRef<string[]>([]);
26+
const colorsCache = useRef<Map<string, Color>>(new Map());
3427

35-
const generateColors = useCallback(async (total: number): Promise<void> => {
36-
setLoadPanelVisible(true);
37-
const promises: Promise<Color | null>[] = [];
28+
useEffect(() => {
3829
for (let i = 0; i < total; i++) {
39-
const hex = getRandomPastelColor();
40-
promises.push(fetchColorData(hex));
30+
hexCodes.current.push(getRandomPastelColor());
4131
}
32+
}, []);
33+
34+
const fetchColorsForPage = useCallback(async (): Promise<void> => {
35+
setLoadPanelVisible(true);
36+
const startIndex = (pageIndex - 1) * pageSize;
37+
const endIndex = startIndex + pageSize;
38+
const hexSubset = hexCodes.current.slice(startIndex, endIndex);
39+
40+
const promises = hexSubset.map((hex) => {
41+
if (colorsCache.current.has(hex)) {
42+
return Promise.resolve(colorsCache.current.get(hex));
43+
}
44+
return fetchColorData(hex).then((color) => {
45+
if (color) {
46+
colorsCache.current.set(hex, color);
47+
}
48+
return color;
49+
});
50+
});
4251

4352
try {
4453
const results = await Promise.all(promises);
4554
const filteredColors = results.filter((color): color is Color => color !== null);
46-
setColors(filteredColors);
55+
setVisibleCards(filteredColors);
4756
} catch (error) {
48-
console.error('Error generating colors:', error);
57+
console.error('Error fetching colors:', error);
58+
} finally {
59+
setLoadPanelVisible(false);
4960
}
50-
}, [total]);
61+
}, [pageIndex, pageSize]);
5162

5263
const onPageIndexChange = useCallback((value: number) => {
5364
setPageIndex(value);
54-
getVisibleCards(value, pageSize);
55-
}, [pageSize, getVisibleCards]);
65+
}, []);
5666

5767
const onPageSizeChange = useCallback((value: number) => {
5868
setPageSize(value);
59-
getVisibleCards(pageIndex, value);
60-
}, [pageIndex, getVisibleCards]);
61-
62-
useEffect(() => {
63-
if (!isMounted.current) {
64-
isMounted.current = true; // Mark as mounted
65-
generateColors(total).catch((error) => {
66-
console.error('Error initializing colors:', error);
67-
});
68-
}
6969
}, []);
7070

7171
useEffect(() => {
72-
if (colors.length > 0) {
73-
getVisibleCards(pageIndex, pageSize);
74-
}
75-
}, [colors]);
72+
fetchColorsForPage().catch((error) => {
73+
console.error('Error updating visible cards:', error);
74+
});
75+
}, [fetchColorsForPage]);
7676

7777
return (
7878
<div className="main">
@@ -94,8 +94,8 @@ function App(): JSX.Element {
9494
onPageSizeChange={onPageSizeChange}
9595
/>
9696
<div id="cards">
97-
{visibleCards.map((color) => (
98-
<div key={color.name}>
97+
{visibleCards.map((color, index) => (
98+
<div key={index}>
9999
<img src={color.image} alt={color.name} />
100100
</div>
101101
))}

Vue/src/components/HomeContent.vue

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
<template>
22
<div class="container">
33
<DxLoadPanel
4-
v-model:visible="loadPanelVisible"
5-
:show-indicator="true"
6-
:show-pane="true"
7-
:hide-on-outside-click="false"
4+
v-model:visible="loadPanelVisible"
5+
:show-indicator="true"
6+
:show-pane="true"
7+
:hide-on-outside-click="false"
88
>
9-
<DxPosition
10-
my="top" at="top" of="#cards"
11-
/>
9+
<DxPosition my="top" at="top" of="#cards" />
1210
</DxLoadPanel>
1311
<DxPagination
14-
:show-info="true"
15-
:show-navigation-buttons="true"
16-
v-model:page-index="pageIndex"
17-
v-model:page-size="pageSize"
18-
:item-count="total"
19-
@update:page-index="onPageIndexChange"
20-
@update:page-size="onPageSizeChange"
21-
/>
12+
:show-info="true"
13+
:show-navigation-buttons="true"
14+
v-model:page-index="pageIndex"
15+
v-model:page-size="pageSize"
16+
:item-count="total"
17+
@update:page-index="onPageIndexChange"
18+
@update:page-size="onPageSizeChange"
19+
/>
2220
<div id="cards">
2321
<div v-for="color in visibleCards" :key="color.name">
2422
<img :src="color.image" :alt="color.name" />
@@ -42,39 +40,59 @@ interface Color {
4240
const total = 100;
4341
const pageSize = ref(5);
4442
const pageIndex = ref(3);
45-
const colors = ref([] as Color[]);
4643
const loadPanelVisible = ref(false);
4744
const visibleCards = ref([] as Color[]);
4845
49-
const generateColors = async () => {
50-
loadPanelVisible.value = true;
51-
const promises = [];
46+
const hexCodes = ref<string[]>([]);
47+
const colorCache = new Map<string, Color>();
48+
49+
const generateHexCodes = () => {
5250
for (let i = 0; i < total; i++) {
53-
const hex = getRandomPastelColor();
54-
promises.push(fetchColorData(hex));
51+
hexCodes.value.push(getRandomPastelColor());
5552
}
56-
const results = await Promise.all(promises);
57-
colors.value = results.filter((color): color is Color => color !== null);
58-
loadPanelVisible.value = false;
59-
getVisibleCards(pageIndex.value, pageSize.value);
6053
};
6154
62-
const getVisibleCards = (pageIndex: number, pageSize: number) => {
63-
visibleCards.value = colors.value.slice((pageIndex - 1) * pageSize, pageIndex * pageSize);
64-
}
55+
const fetchColorsForPage = async () => {
56+
loadPanelVisible.value = true;
57+
const startIndex = (pageIndex.value - 1) * pageSize.value;
58+
const endIndex = startIndex + pageSize.value;
59+
const hexSubset = hexCodes.value.slice(startIndex, endIndex);
60+
61+
const promises = hexSubset.map((hex) => {
62+
if (colorCache.has(hex)) {
63+
return Promise.resolve(colorCache.get(hex));
64+
}
65+
return fetchColorData(hex).then((color) => {
66+
if (color) {
67+
colorCache.set(hex, color);
68+
}
69+
return color;
70+
});
71+
});
72+
73+
try {
74+
const results = await Promise.all(promises);
75+
visibleCards.value = results.filter((color): color is Color => color !== null);
76+
} catch (error) {
77+
console.error('Error fetching colors:', error);
78+
} finally {
79+
loadPanelVisible.value = false;
80+
}
81+
};
6582
6683
const onPageIndexChange = (value: number) => {
6784
pageIndex.value = value;
68-
getVisibleCards(pageIndex.value, pageSize.value);
69-
}
85+
fetchColorsForPage();
86+
};
7087
7188
const onPageSizeChange = (value: number) => {
7289
pageSize.value = value;
73-
getVisibleCards(pageIndex.value, pageSize.value);
74-
}
90+
fetchColorsForPage();
91+
};
7592
7693
onMounted(() => {
77-
generateColors();
94+
generateHexCodes();
95+
fetchColorsForPage();
7896
});
7997
</script>
8098

@@ -84,4 +102,4 @@ onMounted(() => {
84102
justify-content: center;
85103
flex-wrap: wrap;
86104
}
87-
</style>
105+
</style>

jQuery/src/index.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
#container {
2+
margin: 50px;
3+
width: 90vh;
4+
}
5+
16
#cards {
27
display: flex;
38
justify-content: center;

0 commit comments

Comments
 (0)