I am trying to show the option name and values for the added product variant in my Basket.
I currently have it working by grabbing the "merchProductKey" & "merchProductVariantKey" from the ExtendedDataCollection off of BasketLineItem and then using a couple of queries to grab all the options and the actual variants selected options/attributes.
var productOptions = merchelloHelper.Query.Product.GetByKey(new Guid(productKey)).ProductOptions;
var productVariantDisplay = merchelloHelper.Query.Product.GetProductVariantByKey(new Guid(variantKey));
I can then get the value from the attributes by matching the optionKey looping through productOptions:
I've done this before in the controller method when the item is added to the basket by sticking a JSON object into the extended data of the line item. At that point you already have all the information you need and the query is need to be performed anyway (one time and not for each item in the basket as it renders).
NOTE: This code is from a site I'm doing at the moment so it does contain some site specific code (the constant for the extended data key)
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult DoAddToCart(AddItemModel model)
{
var merchello = new MerchelloHelper(false);
Basket.EnableDataModifiers = CurrencyContext.IncludeVatInPricing(model.SiteAlias);
var product = merchello.Query.Product.GetByKey(model.ProductKey);
if (model.OptionChoices != null && model.OptionChoices.Any())
{
var extendedData = new ExtendedDataCollection();
var variant = product.GetProductVariantDisplayWithAttributes(model.OptionChoices);
//// serialize the attributes here as they are need in the design
extendedData.SetValue(Web.Constants.ExtendedDataKeys.CartItemAttributes, JsonConvert.SerializeObject(variant.Attributes));
Basket.AddItem(variant, variant.Name, model.Quantity, extendedData);
}
else
{
Basket.AddItem(product, product.Name, model.Quantity);
}
Basket.Save();
return this.RedirectToCurrentUmbracoPage();
}
I fetch the options in the form of a Tuple where item1 is the option name and item2 is the selected attribute: e.g. item1: Color , item2: Blue
/// <summary>
/// Gets customer choices.
/// </summary>
/// <param name="extendedData">
/// The extended data.
/// </param>
/// <param name="product">
/// The product.
/// </param>
/// <returns>
/// The collection of customer choices (used for variant products in a cart).
/// </returns>
protected static List<Tuple<string, string>> GetCustomerChoices(ExtendedDataCollection extendedData, IProductContent product)
{
var productAttributes = (extendedData.ContainsKey(Web.Constants.ExtendedDataKeys.CartItemAttributes)
? JsonConvert.DeserializeObject<IEnumerable<ProductAttributeDisplay>>(extendedData.GetValue(Web.Constants.ExtendedDataKeys.CartItemAttributes))
: Enumerable.Empty<ProductAttributeDisplay>()).ToArray();
var customerOptionChoices = new List<Tuple<string, string>>();
if (productAttributes.Any() && product != null)
{
// ReSharper disable LoopCanBeConvertedToQuery
foreach (var att in productAttributes)
// ReSharper restore LoopCanBeConvertedToQuery
{
var option = product.ProductOptions.FirstOrDefault(x => x.Key.Equals(att.OptionKey));
if (option != null) customerOptionChoices.Add(new Tuple<string, string>(option.Name, att.Name));
}
}
return customerOptionChoices;
}
Thanks for taking the time to answer this and providing your example code, extremely helpful and exactly what I was looking for in terms of eliminating all the sets of queries per line item on render of the basket.
Displaying Product Options in Basket
I am trying to show the option name and values for the added product variant in my Basket.
I currently have it working by grabbing the "merchProductKey" & "merchProductVariantKey" from the ExtendedDataCollection off of BasketLineItem and then using a couple of queries to grab all the options and the actual variants selected options/attributes.
I can then get the value from the attributes by matching the optionKey looping through productOptions:
If anyone knows a better way to do this (method or object I may have missed!) to reduce the queries - that would be great! Thanks
Hey Danny,
I've done this before in the controller method when the item is added to the basket by sticking a JSON object into the extended data of the line item. At that point you already have all the information you need and the query is need to be performed anyway (one time and not for each item in the basket as it renders).
NOTE: This code is from a site I'm doing at the moment so it does contain some site specific code (the constant for the extended data key)
I fetch the options in the form of a Tuple where item1 is the option name and item2 is the selected attribute: e.g. item1: Color , item2: Blue
Yo Rusty,
Thanks for taking the time to answer this and providing your example code, extremely helpful and exactly what I was looking for in terms of eliminating all the sets of queries per line item on render of the basket.
is working on a reply...