fix: Buy Now raced ahead of addToCart, per-product SEO tags never applied
CartService.addItem() fired an async dynamic import + API call for new items but returned void immediately - buyNow() navigated to /cart before the item was actually added, landing the user on an empty or stale cart. addItem() now returns a Promise that resolves once the cart signal actually contains the item; buyNow() awaits it before navigating. Also wired SeoService.setItemMeta()/resetToDefaults() into the product detail page - built and working, but never called anywhere, so every product page rendered the site-wide default OG/Twitter tags instead of per-product ones. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ import { LanguageService } from '../../../../services/language.service';
|
||||
import { DEFAULT_PRODUCT_PAGE_CONFIG, DEFAULT_USER_EXPERIENCE_CONFIG, ProductPageConfig } from '../../../../shared/models/config';
|
||||
import { getStockStatus, getTranslatedField } from '../../../../utils/item.utils';
|
||||
import { ProductShareService } from '../../user-experience/services/product-share.service';
|
||||
import { SeoService } from '../../../../services/seo.service';
|
||||
import { ProductDeliveryInformationComponent } from '../components/delivery-information/delivery-information.component';
|
||||
import { ProductActionsComponent } from '../components/product-actions/product-actions.component';
|
||||
import { ProductGalleryComponent } from '../components/product-gallery/product-gallery.component';
|
||||
@@ -70,6 +71,7 @@ export class ProductDetailsContainerComponent {
|
||||
private readonly languageService = inject(LanguageService);
|
||||
private readonly translate = inject(TranslateService);
|
||||
private readonly shareService = inject(ProductShareService);
|
||||
private readonly seoService = inject(SeoService);
|
||||
|
||||
readonly productPageConfigState = signal<Required<ProductPageConfig>>(this.resolveProductPageConfig());
|
||||
readonly userExperienceConfig = signal(this.resolveUserExperienceConfig());
|
||||
@@ -229,6 +231,8 @@ export class ProductDetailsContainerComponent {
|
||||
this.route.paramMap
|
||||
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||
.subscribe(params => this.loadProduct(Number(params.get('id'))));
|
||||
|
||||
this.destroyRef.onDestroy(() => this.seoService.resetToDefaults());
|
||||
}
|
||||
|
||||
loadProduct(productId: number): void {
|
||||
@@ -261,6 +265,7 @@ export class ProductDetailsContainerComponent {
|
||||
}
|
||||
|
||||
this.product.set(product);
|
||||
this.seoService.setItemMeta(product);
|
||||
if (this.userExperienceConfig().recentlyViewed.enabled) {
|
||||
this.uxFacade.trackRecentlyViewed(product, this.userExperienceConfig().recentlyViewed.maxItems);
|
||||
}
|
||||
@@ -303,10 +308,10 @@ export class ProductDetailsContainerComponent {
|
||||
}
|
||||
}
|
||||
|
||||
addToCart(): void {
|
||||
addToCart(): Promise<void> {
|
||||
const current = this.product();
|
||||
if (!current) return;
|
||||
this.cartService.addItem(current.itemID, 1, {
|
||||
if (!current) return Promise.resolve();
|
||||
return this.cartService.addItem(current.itemID, 1, {
|
||||
colour: this.selectedColour() ?? undefined,
|
||||
size: this.selectedSize() ?? undefined,
|
||||
price: this.effectivePrice(),
|
||||
@@ -314,9 +319,9 @@ export class ProductDetailsContainerComponent {
|
||||
});
|
||||
}
|
||||
|
||||
buyNow(): void {
|
||||
this.addToCart();
|
||||
this.router.navigate([`/${this.languageService.currentLanguage()}/cart`]);
|
||||
async buyNow(): Promise<void> {
|
||||
await this.addToCart();
|
||||
void this.router.navigate([`/${this.languageService.currentLanguage()}/cart`]);
|
||||
}
|
||||
|
||||
toggleWishlist(): void {
|
||||
|
||||
Reference in New Issue
Block a user