I am trying to do a basic check to see if an image is retina and has a portrait ratio. I have all that checking functionality working perfectly fine. My issue is that in the
Promise is returning [object Promise] then it returns a null value. check the collection of mongo DB and ensure accessing path is correct.
your function return promise so you should call it as promise
<img src={media[i].image} alt={media[i].alt} data-portrait={checkIfPortrait(media[i].image).then(result=>result})};
The basic idea of a promise is that it gives you something to return right away even if it won't resolve until later. It represents its eventual value. So getImageMeta ()
is immediately returning the promise even though it has not resolved.
Once you have the promise returned by getImageMeta ()
you can use its then()
to wait for the final boolean, which will come on the next event loop cycle at the earliest.
With your current code you are saving the promise returned by getImageMeta()
to checkIfPortrait
. So now checkIfPortrait
holds this promise and you can call then()
on it. Since you are exporting checkIfPortrait
you will probably end up calling then on the module that imports it:
// import checkIfPortrait
checkIfPortrait(src)
.then(ret_val => {
//you can access boolean here in ret_val
})
This is the expected result. When you return a new Promise
object, it will always be a promise object ([object Promise]
when stringified).
You access the result of a promise by using the .then
method (or using await
in an async
function). Your .then
callback is then called when/if the result is made available, which will happen after you call resolve
, or if the promise was already resolved prior it will be called rather quickly.
function getImageMeta(src) {
return new Promise(resolve => {
setTimeout(() => {
resolve({metadata: `for: ${src}`});
}, 100);
});
}
getImageMeta('test.png').then(meta => {
console.log(meta); // {"metadata": "for: test.png"}
});
(async () => {
const meta = await getImageMeta('test.png');
console.log(meta); // {"metadata": "for: test.png"}
})();
The issue is now resolved, thanks to everyone for the help. Like stated the issue was I was calling the promise's value before it could be resolved and had no way of updating that value after it had been resolved.
So what I did is made sure the image data was accessible before running the function. Then once I had a resolved promise it then update the image data to show whether it is portrait or not.
So the final code looks like this:
const enhance = lifecycle({
componentWillMount: function () {
Object.keys(this.props.media).map((i) =>
checkIfPortrait(this.props.media[i].image)
? this.props.media[i].isPortrait = true
: this.props.media[i].isPortrait = false
);
}
})
const checkIfPortrait = src => !isRetina(src) ? false : getImageMeta(src).then(res => res);
const isRetina = src => src.indexOf('@2x') !== -1;
const isPortrait = ({ naturalWidth, naturalHeight }) => naturalHeight > naturalWidth ? true : false;
function getImageMeta (src) {
const img = new Image();
img.src = src;
return new Promise((resolve, reject) => {
return img.addEventListener("load", function () {
return resolve(isPortrait(this));
}, false);
});
}
export { checkIfPortrait }
<img src={media[i].image} alt={media[i].alt} data-portrait={media[i].isPortrait} />