3

I’m building a simple portfolio website for a photographer. The collection type that I’m trying to display is called pet pictures, with fields for a title and an image. I’m able to call the API with an async function, but once I have the JSON data from the API, I’m not able to access the URL for the photos. I can create a heading that shows the title of each Pet Picture, for example, but I cannot use standard object notation to access the URL in the JSON data and then display the image. Is this literally impossible? I’m losing my mind a bit.

For example, taking an array of JSON data that looks like this:

{
    "id": 1,
    "Title": "Santa Dog Picture",
    "published_at": "2021-03-29T02:45:32.389Z",
    "created_at": "2021-03-29T02:45:23.362Z",
    "updated_at": "2021-03-29T02:45:32.414Z",
    "Photo": {
        "id": 3,
        "name": "Pets3.jpg",
        "alternativeText": "",
        "caption": "",
        "width": 4000,
        "height": 6000,
        "formats": {
            "thumbnail": {
                "name": "thumbnail_Pets3.jpg",
                "hash": "thumbnail_Pets3_a4be530d90",
                "ext": ".jpg",
                "mime": "image/jpeg",
                "width": 104,
                "height": 156,
                "size": 5.74,
                "path": null,
                "url": "/uploads/thumbnail_Pets3_a4be530d90.jpg"
            },
            "large": {
                "name": "large_Pets3.jpg",
                "hash": "large_Pets3_a4be530d90",
                "ext": ".jpg",
                "mime": "image/jpeg",
                "width": 667,
                "height": 1000,
                "size": 85.36,
                "path": null,
                "url": "/uploads/large_Pets3_a4be530d90.jpg"
            },
            "medium": {
                "name": "medium_Pets3.jpg",
                "hash": "medium_Pets3_a4be530d90",
                "ext": ".jpg",
                "mime": "image/jpeg",
                "width": 500,
                "height": 750,
                "size": 56.22,
                "path": null,
                "url": "/uploads/medium_Pets3_a4be530d90.jpg"
            },
            "small": {
                "name": "small_Pets3.jpg",
                "hash": "small_Pets3_a4be530d90",
                "ext": ".jpg",
                "mime": "image/jpeg",
                "width": 333,
                "height": 500,
                "size": 31.39,
                "path": null,
                "url": "/uploads/small_Pets3_a4be530d90.jpg"
            }
        },
        "hash": "Pets3_a4be530d90",
        "ext": ".jpg",
        "mime": "image/jpeg",
        "size": 2031.2,
        "url": "/uploads/Pets3_a4be530d90.jpg",
        "previewUrl": null,
        "provider": "local",
        "provider_metadata": null,
        "created_at": "2021-03-29T02:42:56.325Z",
        "updated_at": "2021-03-29T02:42:56.464Z"
    }
}

This does not work:

const displayPhoto = async () => {
    const response = await fetch('/pet-pictures')
    const petPictures = await response.json()

console.log(petPictures)
const container = document.querySelector('#pets')


petPictures.forEach((picture) =>{
   
const photo = document.createElement('img')
photo.setAttribute('src', picture.Photo.formats.small.url)
container.appendChild(photo)

})

}

displayPhoto()

I get a TypeError: cannot read property ‘formats’ of undefined. But if I replace photo with title, and create an h1 and set it’s text content to picture.title, that works. I’m losing my mind here! Apologies if I’m missing something super obvious and embarrassing.

JordanK
  • 65
  • 1
  • 5

1 Answers1

1

The only way right now is to add to every image in your app the url and the port that your strapi app is using. For example, if you're running strapi in you local development enviroment in the default port, then you will need to add localhost:1337 as prefix to image url.

The reason is that you are using the default way to upload images in your app and strapi save the url without the domain.

you will have to append the local host or domain before the url. as strapi returns the url path starting from "/uploads"

Below code template should help you:

const displayPhoto = async () => {
const response = await fetch('/pet-pictures')
const petPictures = await response.json()

console.log(petPictures)
const container = document.querySelector('#pets')
const api_url = "localhost:1337"; //Or domain name   

petPictures.forEach((picture) =>{
   
const photo = document.createElement('img')
photo.setAttribute('src', api_url + picture.Photo.formats.small.url)
container.appendChild(photo)

})

}

displayPhoto()

Last, I also think that is a good idea to use an external service like S3 form amazon or blob storage from azure to upload your static files. This problem is not present on those services. I'm using azure blob storage and strapi is saving the files with the correct url. See the image below

Url created on a response using azure blob storage

Here is a provider list that you can use for your project, just remember that the only officially supported package is for AWS.

https://www.npmjs.com/search?q=strapi-provider-upload-

https://strapi.io/documentation/developer-docs/latest/development/plugins/upload.html#upload

Anuj Divkar
  • 252
  • 1
  • 10