Rendering the main_image from the ID

products
images

#1

Hi,

I’m having some issues trying to render product images. I’ve created two test products using the Moltin dashboard and I uploaded images for them. When I hit the API for the product data, I can see the main_image has an ID, but it doesn’t have a file extension.

I can fudge it to work by passing the product.id and the main_image.id into the Amazon S3 url, which does make it render, but only if I guess the file extension correct. If I put .jpg on the end of a .png it doesn’t work (obviously lol).

It seems like there should be a main_image.extension attribute, or a main_image.url attribute I can use to pass into the img tag, but I just can’t seem to find any documentation on how I’m supposed to be handling it.

Thanks,
C


#2

Hey Craig!

The main image is a file, and the main_image ID you get back with the product is related to the main image file resource.

If you then get that file resource from the API, you’ll see the href and other details in the response :slight_smile:

Here’s the bit in the react app that does it, after it gets the products and includes the files and main images -
https://github.com/moltin/react-demo-store/blob/master/src/components/Products/ProductImage.js#L11

This shows how to include other resources in a call https://github.com/moltin/react-demo-store/blob/master/src/utils/moltin.js#L17

Does that make sense?


#3

Hi Matt,

At the moment I’m hitting the API using the following:

  return Moltin.Products.Filter({eq: {slug}}).All();

The object I get back looks like this:

{ type: 'product',
  id: 'abc123ab-123a-1234-ab5c-de67f8gh9ij0',
  name: 'Some product',
  slug: 'some-slug',
  sku: 'sku123',
  manage_stock: true,
  description: 'test',
  price: [ { amount: 1, currency: 'GBP', includes_tax: true } ],
  status: 'live',
  commodity_type: 'physical',
  relationships: { 
    main_image: { 
      data: { 
        type: 'main_image',
        id: '4f454b03-117f-4bde-b6c3-e0cf78065e3d'
      }
    }
  },
  meta: 
   { display_price: { with_tax: [Object], without_tax: [Object] },
     stock: { level: 5, availability: 'in-stock' }
  }
}

I’ve tried chaining With('files, main_images, collections') to the API call but it makes no difference to the response object.

I did read the react example used v1 of the API, could this be the issue?

Thanks,
C


#4

Hi Craig,

When you link a product to a file, we store a relationship from the product to that file. By default we don’t resolve the relationship to the file when you retrieve a product.

To have the related file included in that request, you can add ?include=main_image to the request. To do that with the JS SDK, you can use the With method.

return Moltin.Products.With(['main_image']).All()

The response will then append an included object to the product response.

{
  "data": {
    "type": "product",
    // product data...
  },
  "included": {
    "main_images": [
      {
        "type": "file",
        "id": "7cc08cbb-256e-4271-9b01-d03a9fac9f0a",
        // file object...
      }
    ]
}

The same process works with categories, brands etc. It allows us to keep responses small for those that want them whilst still allowing users to include the data they require.


#5

I believe With needs to be an array rather than a string.


#6

Hi James,

That’s still just doing the same thing.

I’ve tried adding a file in the dashboard, and adding that to the call using .With(['main_image', 'files']), and this adds a file object to the response, so I have the following:

"relationships": {
    "files": {
      "data": [
        {
          "type": "file",
          "id": "785a7376-2fb2-4c2b-b212-0193d0893c34"
        }
      ]
    },
    "main_image": {
      "data": {
        "type": "main_image",
        "id": "4f454b03-117f-4bde-b6c3-e0cf78065e3d"
      }
    }
  },

However, it’s still the same problem as its just an ID and a type. There’s no file extension, or href or url or anything I can use to actually use it in an img tag.

Thanks,
C


#7

Hey @abbott567. Which version of the SDK are you using? @moltin/sdk@2.6.1 is the most up-to-date version published.

The included child that is returned from using the With() method is a top-level object that lives alongside data (where the main attributes for your product record (id, name, description etc) live, along with the relationships object).

Your full response should look something like this :point_down:

{
  "data": {
    "type": "product",
    // product data...
  },
  "included": {
    "main_images": [
      {
        "type": "file",
        "id": "7cc08cbb-256e-4271-9b01-d03a9fac9f0a",
        // file object...
      }
    ]
}

By using the With() method, the API will include the full requested resource objects in the response based on the existing relationships on that resource.

This follows the JSON API spec which you can learn more about here.


#8

Hi Jonathan,

I’ve done an npm update and it appears to be working now! Thanks for all your help.

Thanks,
C


Get product list with images/files -- v1 vs v2
#9

Hi Everyone,

I’m new to Moltin and I got the problem i.e, when I got this :
06

But how it is possible to render the main_image from the ID please ?
I’m trying to build a store made in Angular but that matter is killing me.

Best regards


#10

Hey! :wave: Sorry for the delay in a reply.

Are you using the JavaScript SDK?

That relationship is simply a reference to the actual main_image record. There’s 2 ways you could approach this:

  1. Request the API include the main_image record(s) in the payload. This can be done with the SDK using the following call: Moltin.Products.With('main_image').All(). There’ll then be an included object in the payload which will include the full record object. You can then find that object using the ID from the main_image relationship on the product. This is the recommended approach.
  2. Alternatively you could make a subsequent request to the API to get the file record using the ID in the relationship reference. This would then return the full object for you to use as you wish. However this comes at the cost of an additional network request.

I hope this helps, let me know if you have any questions :smile: