Bram-peter van Zalk
Bram-peter van Zalk

Reputation: 11

Javascript promise image

Just trying to understand the flow of a promise. Have only been learning js for a few weeks, so any help is greatly appreciated. Trying to display a random image from an API with the measurements from the input in the form. However the width and height don't adjust. Im assuming it is because I don't understand the flow of the promise. Thanks!


let width = 600
let height = 300

function imgSize() {
    width = parseInt(document.getElementById('width').value)
    height = parseInt(document.getElementById('height').value)
    loadElement()
}

function loadElement() {
    return new Promise((resolve) => {
        const element = new Image()
        element.src = `https://picsum.photos/${width}/${height}`
        element.onload = () => {
            resolve(element)
        }
    })
}

loadElement().then((element) => {
    document.getElementById('img-container').innerHTML = `<img src=${element.src}/>`
})
body {
   text-align: center;
}
<form id='form' action='VanZalk_ES6_Promises.html'>
    <label for='width'>Enter width of property:</label><br>
    <input type='number' id='width' name="width"><br><br>
    <label for='height'>Enter height of property:</label><br>
    <input type="number" id='height' name="height"><br><br>
    <label for='grey'>Greyscale</label>
    <input type="checkbox" id="grey" name="grey"><br><br>
    <button onclick='imgSize()' id='btn'>Show photo</button><br><br>
    <div id='img-container'>
    </div>
</form>

Update thanks, I think the main problem was retrieving the image. The image is displayed fine on loading the page. However when I submit values for changing the size and hit the button, it goes back to it's previous size. I tried it without using a promise. I tried it using just some text instead of an image. callImg runs fine the first time, but when call it again and it reaches the line of code to change the img.src it jumps the rest of the code. This is what it looks like now:

            let width 
            let height

            let img = new Image()
            let node = document.getElementById('img-container')


            function callImg() {
                if (width === undefined) {
                    width = 200
                    height = 200
                } else {
                width = parseInt(document.getElementById('width').value)
                height = parseInt(document.getElementById('height').value)
                }
                img.src = `https://picsum.photos/${width}/${height}`
                node.appendChild(img)
            }

// just to try to change the width after clicking the button

            function imgSize() {
                width = 800
                callImg()
             }

//calling function on loading the page, so that there will be an image to //start with

            callImg()

Upvotes: 0

Views: 1090

Answers (1)

Jamiec
Jamiec

Reputation: 136114

There is no need for the Promise here*. Also the service you're using supports just putting the width/height into the src directly so just use that in the appended img tag.

function imgSize() {
  width = parseInt(document.getElementById('width').value)
  height = parseInt(document.getElementById('height').value)
  document.getElementById('img-container').innerHTML = `<img src="https://picsum.photos/${width}/${height}">`;
}
<label for='width'>Enter width of property:</label><br>
<input type='number' id='width' name="width"><br><br>
<label for='height'>Enter height of property:</label><br>
<input type="number" id='height' name="height"><br><br>
<label for='grey'>Greyscale</label>
<input type="checkbox" id="grey" name="grey"><br><br>
<button onclick='imgSize()' id='btn'>Show photo</button><br><br>
<div id='img-container'>
</div>


* Not strictly true, the advantage of the code you wrote originally was that by setting the src of an Image instance you're really preloading the image in the background. When then setting the src of the image element, the image is already loaded. You could indeed do this with a promise:

function imgSize() {
  width = parseInt(document.getElementById('width').value)
  height = parseInt(document.getElementById('height').value)
  loadElement().then(img => {
    document.getElementById('img-container').innerHTML = `<img src="${img.src}">`;
  })
}

function loadElement() {
  return new Promise((resolve) => {
    const element = new Image()
    element.src = `https://picsum.photos/${width}/${height}`
    element.onload = () => {
      resolve(element)
    }
  })
}
<label for='width'>Enter width of property:</label><br>
<input type='number' id='width' name="width"><br><br>
<label for='height'>Enter height of property:</label><br>
<input type="number" id='height' name="height"><br><br>
<label for='grey'>Greyscale</label>
<input type="checkbox" id="grey" name="grey"><br><br>
<button onclick='imgSize()' id='btn'>Show photo</button><br><br>
<div id='img-container'>
</div>

Upvotes: 1

Related Questions