Product
obsolete: check how this is referenced now
Extending the Product model
Example:
typescript// shopify/Product.tsclass Product extends BaseProduct {}// components/FooComponent.tslet rewardPoints = 0;for (let tag of product.tags) {if (tag.indexOf('RewardPoints_') === 0) {rewardPoints = Number(tag.substring('RewardPoints_'.length));break;}}// components/BarComponent.tslet hasRewardPoints = false;for (let tag of product.tags) {if (tag.indexOf('RewardPoints_') === 0) {hasRewardPoints = true;break;}}
typescript// shopify/Product.tsclass Product extends BaseProduct {}// components/FooComponent.tslet rewardPoints = 0;for (let tag of product.tags) {if (tag.indexOf('RewardPoints_') === 0) {rewardPoints = Number(tag.substring('RewardPoints_'.length));break;}}// components/BarComponent.tslet hasRewardPoints = false;for (let tag of product.tags) {if (tag.indexOf('RewardPoints_') === 0) {hasRewardPoints = true;break;}}
As a custom getter:
typescript// shopify/Product.tsclass Product extends BaseProduct {get rewardPoints(): number|null {const TAG_PREFIX = 'RewardPoints';for (let tag of product.tags) {if (tag.indexOf(TAG_PREFIX) === 0) {return Number(tag.substring(TAG_PREFIX.length));}}return null;}}// components/FooComponent.tslet rewardPoints = product.rewardPoints;// components/BarComponent.tslet hasRewardPoints = product.rewardPoints != null;
typescript// shopify/Product.tsclass Product extends BaseProduct {get rewardPoints(): number|null {const TAG_PREFIX = 'RewardPoints';for (let tag of product.tags) {if (tag.indexOf(TAG_PREFIX) === 0) {return Number(tag.substring(TAG_PREFIX.length));}}return null;}}// components/FooComponent.tslet rewardPoints = product.rewardPoints;// components/BarComponent.tslet hasRewardPoints = product.rewardPoints != null;
Optimising frequently-accessed custom attributes
If you're adding a new property that's accessed frequently, it can be more efficient to calculate it once, especially if it requires performing loops like the above example.
Option 1: memomized getter
You can make the getter more efficient by simply storing the value after it's first calculated.
typescriptclass Product extends BaseProduct {private _rewardPoints: number|null = -1;get rewardPoints(): number|null {if (this._rewardPoints != -1) {return this._rewardPoints;}let value = null;const TAG_PREFIX = 'RewardPoints';for (let tag of product.tags) {if (tag.indexOf(TAG_PREFIX) === 0) {value = Number(tag.substring(TAG_PREFIX.length));}}this._rewardPoints = value;return value;}}
typescriptclass Product extends BaseProduct {private _rewardPoints: number|null = -1;get rewardPoints(): number|null {if (this._rewardPoints != -1) {return this._rewardPoints;}let value = null;const TAG_PREFIX = 'RewardPoints';for (let tag of product.tags) {if (tag.indexOf(TAG_PREFIX) === 0) {value = Number(tag.substring(TAG_PREFIX.length));}}this._rewardPoints = value;return value;}}
As a shortcut for this, you can also use the memoize utility function.
typescriptimport {memoize} from 'salvo-ts/utils';class Product extends BaseProduct {get rewardPoints(): number|null {return memoize(() => {const TAG_PREFIX = 'RewardPoints';for (let tag of product.tags) {if (tag.indexOf(TAG_PREFIX) === 0) {return Number(tag.substring(TAG_PREFIX.length));}}return null;});}}
typescriptimport {memoize} from 'salvo-ts/utils';class Product extends BaseProduct {get rewardPoints(): number|null {return memoize(() => {const TAG_PREFIX = 'RewardPoints';for (let tag of product.tags) {if (tag.indexOf(TAG_PREFIX) === 0) {return Number(tag.substring(TAG_PREFIX.length));}}return null;});}}
Option 2: Custom property with initialization
Alternatively you could calculate the property at the time the product is loaded/populated.
typescriptclass Product extends BaseProduct {rewardPoints: number|null = null;fromShopifyProduct(obj: Shopify.Liquid.Product): void {super.fromShopifyProduct(obj);// populate rewardPointsconst TAG_PREFIX = 'RewardPoints';for (let tag of obj.tags) {if (tag.indexOf(TAG_PREFIX) === 0) {this.rewardPoints = Number(tag.substring(TAG_PREFIX.length));break;}}}}
typescriptclass Product extends BaseProduct {rewardPoints: number|null = null;fromShopifyProduct(obj: Shopify.Liquid.Product): void {super.fromShopifyProduct(obj);// populate rewardPointsconst TAG_PREFIX = 'RewardPoints';for (let tag of obj.tags) {if (tag.indexOf(TAG_PREFIX) === 0) {this.rewardPoints = Number(tag.substring(TAG_PREFIX.length));break;}}}}