Why does only the last item in JavaScript loops seem to be impacted?

Currently, I am using the gm npm module for image manipulation and have written this code:

for(i=0;i < 4;i++){
    gm("www/img/" + image[i]).crop(550, 406, 0, 0).write(function(err) {
         console.log(this.outname + " created  ::  " + arguments[3]); //success
    });
}

The purpose of this loop is to iterate through the images array and crop each photo, but it seems to only crop the last one. It appears that the issue may be related to function invocation and callbacks, although I haven't reached an advanced level in understanding these concepts yet.

Answer №1

Modify your code as follows:

for (var i = 0; i < 4; i++) {
  (function (i) {
    gm("www/img/" + image[i]).crop(550, 406, 0, 0).write(function(err) {
         console.log(this.outname + " was created :: " + arguments[3]); //success
    });
  }).call(this, i);
}

Otherwise, the value of i will always be 3 whenever your callback function is called.

Answer №2

To ensure proper encapsulation, it is important to create a "closure" over the variable.

JavaScript operates on a function scope basis.

for (i = 0; i < 4; i++)
{
    (function (a)
    {
        gm("www/img/" + image[a]).crop(550, 406, 0, 0).write(function (err)
        {
            console.log(this.outname + " created  ::  " + arguments[3]); //success
        });
    }).call(this,i)
}

Alternatively,

that=this;

for (i = 0; i < 4; i++)
    {
        (function (a)
        {
            gm("www/img/" + image[a]).crop(550, 406, 0, 0).write(function (err)
            {
                console.log(that.outname + " created  ::  " + arguments[3]); //success
            });
        })(i)
    }

edit :

In addition - It is essential to also retain a reference to the arguments, as they may change after IIFE execution.

You can preserve your arguments using:

var args= Array.prototype.slice.apply(arguments)

For example:

function g()

{
for (i = 0; i < 4; i++)
    {
        (function (a)
        {
           console.log(arguments); //huh ? arguments are not a,b,c !!! anymore
        })(i);
    }
}


g('a','b','c') // 0,1,2,3

Therefore, it is necessary to maintain a reference to the arguments due to potential changes post-IIFE.

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

What is the best way to eliminate additional values depending on the one I have chosen?

When utilizing the Vuetify v-autocomplete component with the multiple prop, we are able to select multiple values. How can I deselect other values based on the value I have selected? For instance: If I choose the main value, all others will be deselecte ...

What is the best way to create a custom hook that updates in response to changes in state?

My situation involves a custom hook that handles a specific state variable. After making changes to the state, it doesn't update right away. To solve this issue, I need to subscribe to it using useEffect. The challenge is that I can't directly ...

What is the best way to implement multiple preload scripts for various Electron windows when utilizing electron forge with the webpack template?

I am utilizing the typescript+webpack template provided by electron forge. To load a single preload script with webpack, I need to set the constant called MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY in the package.json file. This constant can be configured like thi ...

Challenges when it comes to exporting files using Firebase Cloud Functions

I've been working with Firebase Cloud Functions using JavaScript, but I'm encountering issues with the import and export statements. Is there a solution to replace them? const firebase = require('firebase'); const config = { apiKe ...

Issue with the Bootstrap navbar dropdown menu functionality not functioning as expected

<head> <link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="24464b4b50575056455464110a150a17">[email protected]</a>/dist/css/bootstrap.min.css" rel=&q ...

Are you encountering issues with retrieving $http results from the cache?

During my initial $http requests, I am saving the results in cache using two functions in my controller. Both functions call the same function in a service which handles the $http request. The first function successfully saves the results in cache, but whe ...

When trying to install express using Node.js npm, an error message 'CERT_UNTRUSTED' is preventing the installation of express

My goal is to set up express on Raspberry Pi for the purpose of using it in a REST API. However, I keep encountering an issue with SSL certification when trying to install it through npm. Despite attempting various solutions found on different forums, I ha ...

Combine all div elements to create a unified image and then proceed to save it as a jpg file before uploading to the server

These are the divs below: <div style="width:800px; height:420px; position:absolute; top:0px; left:0px; z-index:10; background-image: url('https://3t27ch3qjjn74dw66o1as187-wpengine.netdna-ssl.com/wp-content/uploads/2016/05/052516-800x420-vege-Wallp ...

A program that removes rows while also decreasing the overall sum

I have implemented a form that allows users to add labor and its price, while also displaying the assigned labor on the same page underneath. My objective is to have functionality where if a user clicks on delete, it will remove the corresponding table ro ...

The process of showcasing angularjs ng-repeat with a JSON object

I'm attempting to search for product results using AngularJS. I have retrieved a JSON object with my results, an example of which is shown below: [{"store_id":"17","user_id":"29","company_name":"Liquor R Us","company_type":"Alcohol", "phone":"(303) 5 ...

Determine if an option is chosen in multiple select elements using Vanilla JavaScript

In order to determine if a checkbox is checked, we use the following code: let isChecked = event.target.checked But what about multiple select options like the example below? <select name="books[]" multiple> <option value="A">A</option& ...

Manipulating strings within strings with JavaScript

It's been a strange discovery I made while working with JavaScript. Whenever I try to assign a two-word string to a CSS property, like setting the fontFamily property of an HTML element to "Arial Black", it ends up looking something like thi ...

Using Javascript to define cookie values

I'm attempting to use JavaScript to set a cookie that will instruct Google Translate to select the language for the page. I've experimented with setting the cookie based on my browser's cookie selection of a language. <script> $(doc ...

What causes Array.prototype.sort to function differently in Chrome?

As I was attempting to organize an Array, I observed a discrepancy between the behavior in Chrome V79 and Firefox Dev Edition V72 (both desktop versions). Here is the test: console.log([4, 2, 5, 1, 3].sort((a, b) => a>b)); console.log(Array.prototy ...

Load texture programmatically instead of using MTL files

I've successfully loaded an OBJ file and linked it with an MTL to provide a texture. However, I'm struggling to specify which texture should be associated with the model directly in the code; it seems that the texture only appears on the model if ...

Is there a way to dynamically update CSS files with JavaScript?

Hey, I'm having some trouble altering the values on my HTML page using JavaScript and CSS. Unfortunately, it's not working as expected. Can someone please take a look at my code and help me out? // Displaying persons and their records for ...

Angular: facing difficulty displaying static html pages on server, although they render correctly when run locally

Within my Angular project, I have stored a few static html files (specifically sampleText.html) in the src/assets/html folder. In one of my components, I am attempting to fetch and display this file. The following code is being used for this purpose. Every ...

Tips for successfully transferring the nested service and retrieving the response from an Angular factory to a controller

After making the Http Request and receiving the response from the first Service call, I then pass that response from the first service into the second service and receive the response back to the controller. Now that I have the response, I need to find a ...

I am unable to retrieve dynamic data from the database

Storing data in a MySQL database has been successful for me. I've been utilizing PDO in PHP to fetch the data and then converting it to JavaScript using json_encode. However, I keep encountering the output NaN when implementing a specific scenario. It ...

Grab the code snippet from JSFiddle

I apologize for the seemingly simple question, but I have been struggling with it. I tried looking at similar questions, but I couldn't find a solution. Despite copying the code from http://jsfiddle.net/sB49B/21/, I can't seem to get it to work ...