Link to home
Start Free TrialLog in
Avatar of Crazy Horse
Crazy HorseFlag for South Africa

asked on

How to use .each in an ajax call

I am trying to upload multiple images and the file names are storing in the database like I want but I get a console error that says: $.each(...).done is not a function

$("#edit_pic").on("click", function (e) {
			e.preventDefault();
			var files = $('input[name="file"]').val()
			var data = JSON.parse(files)
		}

		$.each(data, function (index, item) {

			$.ajax({
				url: 'functions/add-support-images.php',
				type: 'POST',
				dataType: 'json',
				data: {
					data: item.file_name
				},
				beforeSend: function () {
					$("#edit_pic").prop("disabled", true).html("Uploading...");
				},
			});
		})

		.done(function (data) {
			if (!data.success) {
				console.log(data.message);


			} else {

				console.log(data.message);

			}

		})

		.fail(function (jqXHR, textStatus, errorThrown) {
			console.log(textStatus + ': ' + errorThrown);
			console.warn(jqXHR.responseText);
		});

Open in new window

Avatar of zephyr_hex (Megan)
zephyr_hex (Megan)
Flag of United States of America image

One problem is that data is defined outside the scope of where you're using $.each.  Have you tried moving your loop inside the $("#edit_pic") function ?

Also, what is the structure of data ?  You can see by doing console.log(data) right after the line where var data is defined.
Avatar of Crazy Horse

ASKER

I updated the code to this and the error has gone away. But now my success message displays as many times as number of files I select.

      
$.each(data, function (index, item) {


	$.ajax({
		url: 'functions/add-support-images.php',
		type: 'POST',
		dataType: 'json',
		data: {
			data: item.file_name,
			id: id
		},
		beforeSend: function () {
			$("#edit_pic").prop("disabled", true).html("Uploading...");
		},
	})

	.done(function (data) {
		if (!data.success) {
			console.log(data.message);


		} else {

			$("#image_success").append(data.message).fadeIn();


		}
	})

	.fail(function (jqXHR, textStatus, errorThrown) {
		console.log(textStatus + ': ' + errorThrown);
		console.warn(jqXHR.responseText);
	});
});

Open in new window

The result of console.log(data) is:

0:{file_name: "pic1"}
1:{file_name: "pic2"}
2:{file_name: "pic2"},
length:3

pic1, pic2, pic3 are the names of the image files that I selected.
That's because the "done" callback happens after each ajax call, and the ajax call is inside the loop.  If you want it to happen once, after all ajax calls, you'll need to use a variable that tracks success (perhaps a counter), and then display your message after the each loop completes (if the variable / counter is the value you expect it to be)
Or, you could track the number of loops and display the success on the last iteration of the loop....  again, you'll probably want to use a counter or something to verify each loop reaches the success ballback.  Then, check if it's the last loop, and on the last loop, display your message
ASKER CERTIFIED SOLUTION
Avatar of zephyr_hex (Megan)
zephyr_hex (Megan)
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you. I will try that out as soon as I am in front of my development pc.