0

How do I pass a dynamic variable image[i] into the .forEach() function?
I get this error when I try to use my variable: Uncaught SyntaxError: Invalid destructuring assignment target

images.forEach((image[i]) => {
  if(iter == 0){ ctx.drawImage(image[i], 60, 270);}
  if(iter == 1){ ctx.drawImage(image[i], 80, 270);}
  if(iter == 2){ ctx.drawImage(image[i], 100, 270);}
  console.log(iter);
});  

Edit:

Here is the whole function

    // Account UI
    function accountUI(str) {
        // Parse MOTD for use
        var motd = str.match( /<motd>[^<>]*?<\/motd>/igm );

        // Clean un-needed spaces & tags
        var motd_clean = motd[0];
        motd_clean = motd_clean.replace("<motd>", "");
        motd_clean = motd_clean.replace("</motd>", "");
        motd_clean = motd_clean.replace(/[\r]+/g, '');
        motd_clean = $.trim(motd_clean);

        // Create textarea for MOTD
        $("#can_wrapper").append('<textarea id="motd" name="motd" disabled>' + motd_clean + '</textarea>');

        // Create blue background for players
        ctx.fillStyle = "#333399";
        ctx.fillRect(2, 255, 596, 181);

        // Parse player names for use
        var players = str.match( /<players>([\s\S]*?)<\/players>/m );
        var players = players[0];
        var item = str.match( /<item([\s\S]*?)>/mg );

        // For every player run iteration
        var image = [];
        for (var i = 0; i < item.length; ++i) {
            // Position for players on account screen
            if(i == 0){ var pos = "61px";var iter = 0;}
            if(i == 1){ var pos = "168px";var iter = 1;}
            if(i == 2){ var pos = "275px";var iter = 2;}
            console.log(i);
            console.log("1 -> " + iter);
            // Gets player name from string
            var player = item[i].match( /([A-Z])\w+/g );

            // Create player div for mouse interaction
            var player_el = $('<div class="cursor player" id="player'+ player +'"></div>');
            $("#can_wrapper").append(player_el);
            $("#player"+ player).css({"position": "absolute", "height": "50px", "width": "50px", "left": ""+ pos +"", "top": "271px", "cursor": "grab", "cursor": "-webkit-grab"});

            // Get player name for hover action
            var player_name_el = player;
            document.styleSheets[0].addRule('#player'+ player +':hover::after','content: "'+player_name_el+'";');

            /**
             * Promisify loading an image
             * @param {String} imagePath The web location of the image
             * @returns {Promise} A Promise that will resolve to an Image
             */
            function loadImage(imagePath) {
                return new Promise((resolve, reject) => {
                    image[i] = new Image();
                    image[i].addEventListener("load", () => {
                        resolve(image[i]);
                    });
                    image[i].addEventListener("error", (err) => {
                        reject(err);
                    });
                    image[i].src = 'https://www.example.com/interface/images/body/' + imagePath;
                });
            }

            var imageSources = ['v1456.png', 'vbody0.png','vhead14.png','v1960.png','v578.png','v1221.png', 'v3063.png']; // url and order

            Promise
                .all(imageSources.map(ii => loadImage(ii)))
                .then((images) => {
                    images.forEach((image[i]) => {
                        if(iter == 0){ ctx.drawImage(image[i], 60, 270);}
                        if(iter == 1){ ctx.drawImage(image[i], 80, 270);}
                        if(iter == 2){ ctx.drawImage(image[i], 100, 270);}
                        console.log(iter);
                    });
                }).catch((err) => {
                    console.error(err);
                });

        }
    }
1
  • Look at the documentation, you don't need the [i] as the first parameter is the current value Commented Mar 20, 2019 at 8:21

3 Answers 3

4

The variable before the => is the name you give each item of the array you're forEaching on in the loop. You don't need to use the [] notation, just a name:

images.forEach((image) => {
  if(iter == 0){ ctx.drawImage(image, 60, 270);}
  if(iter == 1){ ctx.drawImage(image, 80, 270);}
  if(iter == 2){ ctx.drawImage(image, 100, 270);}
  console.log(iter);
});
Sign up to request clarification or add additional context in comments.

1 Comment

Also it looks like iter is the iteration, which atm seems like is outside the loop. However forEach allows you to pass a second parameter which is the index, as shown in the docs
0

You don't need to create a global image array, try following code

You also can use Promise.map

// Account UI
function accountUI(str) {
	// Parse MOTD for use
	var motd = str.match(/<motd>[^<>]*?<\/motd>/igm);

	// Clean un-needed spaces & tags
	var motd_clean = motd[0];
	motd_clean = motd_clean.replace("<motd>", "");
	motd_clean = motd_clean.replace("</motd>", "");
	motd_clean = motd_clean.replace(/[\r]+/g, '');
	motd_clean = $.trim(motd_clean);

	// Create textarea for MOTD
	$("#can_wrapper").append('<textarea id="motd" name="motd" disabled>' + motd_clean + '</textarea>');

	// Create blue background for players
	ctx.fillStyle = "#333399";
	ctx.fillRect(2, 255, 596, 181);

	// Parse player names for use
	var players = str.match(/<players>([\s\S]*?)<\/players>/m);
	var players = players[0];
	var item = str.match(/<item([\s\S]*?)>/mg);

	// For every player run iteration
	
	for (var i = 0; i < item.length; ++i) {
		// Position for players on account screen
		if (i == 0) { var pos = "61px"; var iter = 0; }
		if (i == 1) { var pos = "168px"; var iter = 1; }
		if (i == 2) { var pos = "275px"; var iter = 2; }
		console.log(i);
		console.log("1 -> " + iter);
		// Gets player name from string
		var player = item[i].match(/([A-Z])\w+/g);

		// Create player div for mouse interaction
		var player_el = $('<div class="cursor player" id="player' + player + '"></div>');
		$("#can_wrapper").append(player_el);
		$("#player" + player).css({ "position": "absolute", "height": "50px", "width": "50px", "left": "" + pos + "", "top": "271px", "cursor": "grab", "cursor": "-webkit-grab" });

		// Get player name for hover action
		var player_name_el = player;
		document.styleSheets[0].addRule('#player' + player + ':hover::after', 'content: "' + player_name_el + '";');

		/**
		 * Promisify loading an image
		 * @param {String} imagePath The web location of the image
		 * @returns {Promise} A Promise that will resolve to an Image
		 */
		function loadImage(imagePath) {
			return new Promise((resolve, reject) => {
				let image = new Image();
				imag.addEventListener("load", () => {
					resolve(image);
				});
				image.addEventListener("error", (err) => {
					reject(err);
				});
				image.src = 'https://www.example.com/interface/images/body/' + imagePath;
			});
		}

		var imageSources = ['v1456.png', 'vbody0.png', 'vhead14.png', 'v1960.png', 'v578.png', 'v1221.png', 'v3063.png']; // url and order

		Promise.all(imageSources.map(ii => loadImage(ii))).then((images) => {
			images.forEach((image) => {
				if (iter == 0) { ctx.drawImage(image, 60, 270); }
				if (iter == 1) { ctx.drawImage(image, 80, 270); }
				if (iter == 2) { ctx.drawImage(image, 100, 270); }
				console.log(iter);
			});
		}).catch((err) => {
			console.error(err);
		});

	}
}

4 Comments

This gives me: index.html:419 TypeError: Cannot read property '0' of undefined for the images[i] in the 3 ctx.drawImage(images[i], 60, 270
just looked at your updated question you need only image, which is already answered.
Thanks for the help. I'm guessing it draws the image as it should, it shows that it drew 21 images in the 3rd iteration. Meaning my if (iter == 1) are not working, and everything is drawing on the last one.
change all var to let specially in first for loop
0

You could move the parameters into an array and call the values with an index.

images.forEach(image => ctx.drawImage((image[i], [60, 80, 100][iter], 270)):

3 Comments

I get this error: index.html:414 TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type im guessing because its still expecting image[i]
where is i coming from?
Line 27 in the updated part of my question. for (var i = 0; i < item.length; ++i) {

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.