spree/spree-api-v2-js-sdk

[Question] How to access easily to image urls from Products(list) API?

hoshinotsuyoshi opened this issue ยท 2 comments

Hi there,
this is a question issue.

Is there some simple way to access easily to image urls from Products list API?

I wrote an accessing code, but it is a bit complex.

<template>
  <div>
    <div v-for="product in products" :key="product.id">
      <p>
        {{ product.id }}
        {{ product.attributes.name }}
        <img :src="product.image.attributes.styles[4].url" />
      </p>
    </div>
  </div>
</template>

<script>

import { makeClient } from '@spree/storefront-api-v2-sdk/dist/client'
export default {
  data(){
    return {
      loading: true,
      products: [],
    }
  },

  mounted() {
    (async() => {
      const client = makeClient({
        host: 'http://localhost:3000',
      })
      const response = await client.products.list({
        include: 'images',
        page: 1,
      })
      const success  = response.success();
      const products = success.data;
      const images   = success.included;

      // a bit complex ...
      products.forEach((p, _i) => {
        const image_id = p.relationships.images.data[0].id;
        const found_image = images.find(image => image.id === image_id);
        p.image = found_image;
      })

      this.products = products;
    })();
  },
}
</script>

This seems to work, but it feels verbose.

Is there an easy way to access OpenAPI relationships with JavaScript props and functions?

I also found way to use a npm module jsonapi-deserializer , and this seems to work, too.

<template>
  <div>
    <div v-for="product in products" :key="product.id">
      <p>
        {{ product.id }}
        {{ product.name }}
        <img :src="product.images[0].styles[4].url" />
      </p>
    </div>
  </div>
</template>

<script>

import { makeClient } from '@spree/storefront-api-v2-sdk/dist/client'
import { deserialize } from 'jsonapi-deserializer';
export default {
  data(){
    return {
      loading: true,
      products: [],
    }
  },

  mounted() {
    (async() => {
      const client = makeClient({
        host: 'http://localhost:3000',
      });
      const response = await client.products.list({
        include: 'images',
        page: 1,
      });
      const success  = response.success();
      const products = deserialize(success);
      this.products = products;
    })();
  },
}
</script>

Is it normal to use an external module for deserialization like this?

How do you solve some kind of this, folks?

Hi @hoshinotsuyoshi ๐Ÿ‘‹ ,

Spree returns links to all images and in all sizes. There's a lot of data to process. The benefit is you can find the image that best fits your use case. If you want Spree to return a simpler structure you need to extend the default Spree API serialisers in Spree and then extend the Spree SDK to support the changes.

There are multiple libraries for processing JSON_API responses. jsonapi-deserializer is one of them. Orbit (https://github.com/dgeb/orbit-jsonapi) is another. We found the cost of using them to be greater than the benefit. But if they help you process responses from Spree then go for it ๐Ÿ‘
Alternatively, you can copy and use two helper functions called findIncluded and findIncludedOfType: https://github.com/spark-solutions/spree2vuestorefront/blob/d88d85ae1bcd2ec99b13b81cd2e3c25600a0216e/src/utils/index.ts. They make finding related records much easier. We use them for finding images here: https://github.com/spark-solutions/spree2vuestorefront/blob/d88d85ae1bcd2ec99b13b81cd2e3c25600a0216e/src/importers/product.ts#L74.

Hi @tniezg ๐Ÿ‘‹

If you want Spree to return a simpler structure you need to extend the default Spree API serialisers in Spree and then extend the Spree SDK to support the changes.

Oh that's it. that's true.

We found the cost of using them to be greater than the benefit. But if they help you process responses from Spree then go for it ๐Ÿ‘

I see. Thank you!

Alternatively, you can copy and use two helper functions called findIncluded and findIncludedOfType: https://github.com/spark-solutions/spree2vuestorefront/blob/d88d85ae1bcd2ec99b13b81cd2e3c25600a0216e/src/utils/index.ts. They make finding related records much easier. We use them for finding images here: https://github.com/spark-solutions/spree2vuestorefront/blob/d88d85ae1bcd2ec99b13b81cd2e3c25600a0216e/src/importers/product.ts#L74.

This repository may be a good reference implementation for me.
Thanks for this, too.