js-buy-sdk: [1.0alpha] Line items for products without variants don't have images

After retrieving a checkout via fetchCheckout, I’d like to display the images associated with the line items.

If an item does not have variants though, the variant field of the lineItem is a nonspecified default variant with Default Title as title and null as image. This means that for such a line item, one must fetch all products, match all variants of all products with the lineItem variant id to find the original product, and use the image for that product. This is clearly not optimal.

Steps to reproduce:

  • Create a product with no variants
  • Add a product image
  • Add the product to a checkout
  • The lineItem in the checkout won’t have any reference to the image

Some possible solutions:

  • Make the default variant inherit the product images (and possibly other attributes such as title)
  • Add a product reference to the variant field of lineItems (which should already be, according to the productVariant documentation and the type info for the variant field returned with the query)

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 1
  • Comments: 18 (8 by maintainers)

Most upvoted comments

Same problem here.

I came up with a pretty hacky solution and thought I’d share and get some opinions on the solution.

Use case

Lots of products without variants, a cart that should display the product’s image since the default variant doesn’t carry over the product image.

Idea

Reading the API docs, a lineItem consists of variantId, quantity and optional customAttributes. I modified my addToCart function to add the product by variantId and additionally add the current product image url as a custom attribute. The cart then needs to check if a variant image is present, to comply with normal variant image behavior. If no variant image is present but the lineItem has a certain custom attribute use this as image url.

Code

addToCart = (variantId, productImg) => {

    const lineItemsToAdd = [{variantId, quantity: 1, customAttributes: {key: 'thumbnail', 'value': productImg}}];
    const checkoutId = this.checkout.id

    Client.addLineItems(checkoutId, lineItemsToAdd).then(checkout => {
      this.checkout = checkout
    });
  }

As I said it’s hacky since custom attributes are not meant to be used in this way but when I just ignore the attributes while processing the order I can’t see any direct drawbacks.

Feedback is very welcome.

This looks like a poor modelling choice on our part. The rightish way to do this would be to fetch the line item, with the variant, and the variants product, and it’s images. This seems kinda weird.

I’ve filed an issue internally, and I’ll report back once we figure out a good way to fix this. Thanks for pointing this out!

This PR addresses the issue.

For the babel plugin, the plugin must be in your babelrc. It’s parsed at build time. Relay’s babel plugin works the same way. If you’re getting the error, babel isn’t running this plugin.

For the compiler , the build artifact may be broken. It sounds like the license is being injected incorrectly.