The properties naturalWidth and naturalHeight are both returning a value of zero

There is a code in place to check the ratio of images, which usually works well but occasionally fails when img.naturalWidth and img.naturalHeight return 0. Although this could be due to the image not being fully loaded at that moment, it's puzzling why it happens sporadically. The code is enclosed within reader.onload as per common online solutions.

isValidFileRatio(selectedFile: Blob, width: number, height: number): any {
return new Promise((resolve, reject) => {
  const reader = new FileReader();

  const img = new Image();
  img.src = window.URL.createObjectURL(selectedFile);

  reader.readAsDataURL(selectedFile);
  reader.onload = () => {
    const ratio = img.naturalWidth / img.naturalHeight;
    
    resolve(ratio >= 1 && ratio <= 2);
  };
  reader.onerror = (error) => reject(error);
});

}

Any help or suggestions on resolving this issue would be greatly appreciated. Thank you!

Answer №1

The usage of new FileReader() seems unnecessary and may be the cause of this bug. I recommend modifying your code as shown below:

isValidFileRatio(selectedFile: Blob, width: number, height: number): any {
    return new Promise((resolve, reject) => {
        const img = new Image();
        img.src = window.URL.createObjectURL(selectedFile);
        
        img.onload = () => {
            const ratio = img.naturalWidth / img.naturalHeight;

            resolve(ratio >= 1 && ratio <= 2);
        };
        img.onerror = (error) => reject(error);
    });

Answer №2

The issue at hand lies in your use of filereader.onload as opposed to image.onload

If it were up to me, I would have approached the problem differently:

Instead of relying on FileReader, Image, or Canvas, with their mix of callbacks and promises, I would opt for createImageBitmap.

In my coding practices, I prefer breaking out of promise chains whenever feasible by keeping most of my code synchronous. This way, my functions remain independent from asynchronous operations.

/**
 * @param {{ width: number, height: number }} image
 */
function isValidFileRatio (image) {
  const ratio = image.width / image.height
  return ratio >= 1 && ratio <= 2
}

// Generating a simple dummy image/png blob for demonstration purposes
var blob = new OffscreenCanvas(300, 200).getContext('2d').canvas.convertToBlob()

blob
  .then(createImageBitmap)
  .then(isValidFileRatio)
  .then(console.log)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Allowing Users to Easily Copy CSS ::before Content

Text inserted via pseudo-elements like ::before and ::after cannot be selected or copied. Is there a way to change this behavior? span::before { content: "including this text"; } <p> When the text of this paragraph is selected and copied, ...

Run a section of code located in a different file

I have defined some global functions in main.js like this: Vue.prototype._isMobile = function () { return $(window).width() < 768 } //Few more similar functions Now, I want to move these functions to a separate file called util.js: return (function ...

Utilizing JavaScript to Invoke Controller Actions

Currently, my ASP.NET MVC actions return JSON data, which is then displayed on the screen by my client using jQuery's ajax function. The JavaScript code I use to call these controller actions includes absolute paths like this: $.ajax({ url: &apos ...

Using jQuery and JavaScript to swap images depending on the option chosen in a dropdown menu

On my existing ecommerce website, I have a dropdown menu with the following code: <select data-optgroup="10201" class="prodoption detailprodoption" onchange="updateoptimage(0,0)" name="optn0" id="optn0x0" size="1"><option value="">Please Selec ...

Troubleshooting the Ui-router refresh problem

I set up my ui-router configuration as follows: app.config(function($stateProvider, $urlRouterProvider, $locationProvider) { $stateProvider .state('home', { url: "/home", templateUrl : 'h ...

I am looking to modify the background color of characters in a text box once the characters in a textarea exceed 150 characters

Currently, I am utilizing event.data to capture the text inputted into this particular HTML textbox. My intention is to change the background color to red based on that input. However, when using the style attribute on event.data, I encounter an error. It& ...

The scroll function triggers even upon the initial loading of the page

Trying to solve the challenge of creating a fullscreen slider similar to the one described in this question, I created a jsfiddle (currently on hold) Despite knowing that scrolling too fast causes bugs and that scrolling both ways has the same effect, m ...

Build modern web applications with Visual Studio 2015/2017 using React and TypeScript for dynamic

Has anyone successfully found a comprehensive react+typescript tutorial for a Visual Studio 2015/2017 MVC project that actually works, from beginning to end? I attempted to install the NuGet packages "Reactjs Mvc4" and "typescript", created a .tsx file, a ...

How to create a collapse feature that allows only one item to be open at a time in Angular

I developed an angular app with a collapse feature, but I noticed that multiple collapses can be open at once. I am utilizing Ng-Bootstrap collapse for this functionality. Below is the code snippet from the TS file: public isCollapsed = true; And here is ...

Exploring the depths of AngularJS through manual injection

I seem to have misunderstood the tutorial and am struggling to get manual injection working on my project. As I'm preparing to minify and mangle my JS code, I decided to manually inject all my modules and controllers. However, I keep encountering err ...

Making the Select Tag function as an on-click event in JQuery

So I currently have a tab set up that functions as on click links when viewed on desktop. However, for tablet and mobile devices, I need it to be transformed into a select drop down list while maintaining the same functionality. Below is the code used for ...

Revisiting unions with TypeGraphQL

Here is the code snippet I'm working with: const retrieveUsers = ({ Model, options, }) => Model.find(options).catch((e) => { throw e; }); @ObjectType({ description: "User model" }) @Entity() export class UserModel extends BaseEnti ...

What is the method for transferring form data to a different page?

Currently utilizing AngularJS version 1.5.6 and looking for guidance on properly passing form data using $location.path. Below is my code snippet for Page A: <form> ... <button type="submit" ng-click="submit(formData)"> ...

The renderValue property is malfunctioning in the Material-UI native Select component

Whenever I utilize the native prop in the MUI Select component, the renderValue prop fails to function properly. Additionally, if I attempt to assign a custom value to the value prop, it does not display. Take a look at the code snippet below: const [selec ...

Solving automatically generated TypeScript MongoDB types for GraphQL results

Utilizing the typescript-mongodb plugin along with graphql-codegen to automatically generate Typescript types enables easy data retrieval from MongoDB and GraphQL output via Node. The initial input schema in GraphQL format appears as follows: type User @ ...

Error encountered during Jest snapshot testing: Attempting to destructure a non-iterable object which is invalid

I am currently facing an issue with my React codebase where I am attempting to create snapshot tests for a component. However, Jest is showing an error indicating that I am trying to destructure a non-iterable instance. Despite thoroughly reviewing the cod ...

Adjust camera focus towards object and utilize the lookAt() method (React three fiber)

Seeking a smooth transition for camera.position and camera.lookAt as I switch between "zoomed out" and "zoomed in" views of individual objects randomly placed. The positioning aspect is working smoothly, but lerping the lookAt() function seems to be causi ...

How can variables from state be imported into a TypeScript file?

Utilizing vue.js along with vuetify, I have a boolean value stored in state via Vuex defined in src/store/index.ts (named darkMode). This value is used within one of my view components inside a .vue file. However, I now wish to access the same variable in ...

Changes in the styles of one component can impact the appearance of other

When it comes to styling my login page, I have specific stylesheets that I include in login.component.ts. For all the common CSS files, I have added them in the root index ("index.html") using the traditional method. However, after a user logs into the sys ...

HMR: The webpack-hot-middleware is not refreshing my webpage

My Vue application, titled hello-world, is utilizing webpack-dev-middleware and webpack-hot-middleware. When running the application, it shows that it's connected in the console. However, after making changes to my main.js file, the following message ...