2

i am using unsplash api to show images.i want to download the image when user click on download icon.But i don't know how to add this functionality.here is what i did so far.In the below code i fetch the images from unsplash api and display them in imageContainer by using display grid ...

  • here is my html*
    <!-- image container -->
    <div class="imageContainer grid mt-10 p-2"></div>

    <!-- image popup container -->
    <div class="container height content z-20">
      <div class="icons">
        <i class="fa-solid fa-arrow-down downloadIcon"></i>
        <i class="fa-solid fa-xmark crossIcon"></i>
      </div>
      <div class="imgShowed imgfit z-20"></div>
    </div>
 
  • here is my js*

let imageContainer = document.querySelector(".imageContainer");
let imgShowed = document.querySelector(".imgShowed");
let container = document.querySelector(".container");
let crossIcon = document.querySelector(".crossIcon");
let downloadIcon = document.querySelector(".downloadIcon")
// function to fetch image
function getimage() {
  imageContainer.innerHTML = "";
  (url =
    "https://api.unsplash.com/search/photos?query=" +
    input.value +
    "&per_page=1200&client_id=5OXcnxdQpZLtAG0_jRNpqEQhTlUOQL3TKviFAUbBKm8"),
    fetch(url)
      .then((response) => {
        return response.json();
      })
      .then((data) => {
    
        data.results.forEach((element) => {
          let Div = document.createElement("Div");
          Div.setAttribute("class", "imgDiv");
          Div.setAttribute("data-downloadurl", `${element.links.download}`);
          let img = document.createElement("img");
          img.src = `${element.urls.regular}`;
          Div.appendChild(img);
          document.querySelector(".imageContainer").appendChild(Div);
          imagepopup()
        });
      });
}
document.getElementById("btn").addEventListener("click", getimage);

// image popup function
function imagepopup(){
  let imgDiv = document.querySelectorAll(".imgDiv");
  imgDiv.forEach(element => {
    element.addEventListener("click",(e)=>{
      container.style.display="block"
      let target = e.currentTarget
      let clickedimagesrc = target.firstChild.src
      imgShowed.innerHTML=`<img src="${clickedimagesrc}" class="imgfit" alt="...">`
      downloadIcon.addEventListener("click",()=>{
        let url=target.dataset.downloadurl
        downloadIMG(url)
      })
    })
  });
}

function downloadIMG(){
  const link = document.createElement('a');
  link.style.display = 'none';
    link.href = URL.createObjectURL(url);
    link.download = file.name;
    link.click();
}

1 Answers1

0

I'm currently using Vuejs, but you can adapt it to yours. You will need to convert the download imageUrl to a blob and use the window.URL.createObjectURL method to get the url.

Use the generated URL in anchor tag and use the download attribute.

<a :href="imageDownloadUrl" :download="idModal">Download</a>


data() {
    return {
        imageDownloadUrl: "",
    };
},

methods: {
    async toDataURL(url) {
        const response = await fetch(url);
        const blob = await response.blob();
        const imageUrl = window.URL.createObjectURL(blob);
        // console.log(imageUrl);
        this.imageDownloadUrl = imageUrl;
    },

    getImageUrl(id) {
        const url = this.$store.state.baseURL;
        const key = this.$store.state.apiKey;
        const ixid =
            "MnwxMTc4ODl8MHwxfHNlYXJjaHwxfHxwdXBweXxlbnwwfHx8fDE2MTc3NTA2MTM";

        const endpoint = `${url}/photos/${id}/download?ixid=${ixid}&client_id=${key}`;

        // the endpoint it's like: https://api.unsplash.com/photos/imageId/download?ixid=ixId&client_id=apiKey
        
        // the full path can be found in **links.download_location** of the returned array of images, also get your **ixid** from the link and make sure to include apiKey.

        axios
            .get(endpoint)
            .then((response) => {
                let url = response.data.url;
                this.toDataURL(url);
            })
            .catch((error) => {
                console.log(error);
            });
    },
},

NOTE: If you're using the example from the link below, try not to return window.URL.createObjectURL(blob) as you'll have a promise, but since you only need the url simply save it to a variable and use it as the href value for the anchor tag with a download attribute (as above)...the download attribute value is optional.

Helpful links:

Vanilla js implementation: How can I create a button which Fetches image from API and download to the local with using ReactJs

Download file with anchor tag: How to make PDF file downloadable in HTML link?

createObjectURL explained: https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL

Okiemute Gold
  • 459
  • 3
  • 10
  • I am looking into your issue but as I found here its saying chrome as a deprecated cross-origin URL to download https://stackoverflow.com/questions/17527713/force-browser-to-download-image-files-on-click – Azeez May 28 '22 at 21:07
  • if you see the second answer may be that can help you – Azeez May 28 '22 at 21:08
  • If you mean the answer with a downloadImage function... Then that should work. Same as above though... In @nidhi-sharma code, within the forEach loop, you can get each 'element.links.download_location' saved to a variable, say: downLoadUrl, and pass it as an argument in the function toDataUrl above, to get the URL used in tag for download... – Okiemute Gold May 30 '22 at 10:02