0

Explanation of the code:

In the first .then(), I'm getting the data of 10 images. Then using a for of loop, I'm traversing on each individual image. In the next line, I'm generating a different path to save the image to hence the ${count}.

Now the main part

I'm using axios to get the image by passing in the image.url. In the .then(), I'm getting the response and I'm piping it to the path I generated beforehand.

Resolving if data is fetched and incrementing the count to change the path in the next iteration. Rejecting if any error occurs

I'm doing console.log(count++) to check if I'm iterating over all 10 images and i'm getting '1 2 ....10' output which means everything is working fine.


Problem: Acc to the code, 10images should be saved in the images folder with names 'image1, image2 ...image10'. But I'm getting just the first image. What am I doing wrong? Should writing stuff to the disk be done in for loops?

client.search('Steve Angello')
.then(images => {
    let count = 1;

    for(image of images){
        const path1 = path.resolve(__dirname, 'images', `image ${count}.jpg`);
        axios({
            method: 'GET',
            url: image.url,
            responseType: 'stream'
        })
        .then((response) => {
                response.data.pipe(fs.createWriteStream(path1));

                return new Promise( (resolve, reject) => {
                    response.data.on('end', () => {
                        resolve();
                        console.log(count++);
                    })

                    response.data.on('error', (error) => {
                        reject(error);
                    })
                })
            })
        .catch((err) => console.log(err));   
    }

});

Snapshot of the output

Harshit Khanna
  • 93
  • 1
  • 1
  • 6
  • Can you try `let path1` instead of `const path1` – bird Feb 22 '19 at 18:31
  • Please include the input and output as text, not as images. – Heretic Monkey Feb 22 '19 at 18:33
  • Also, you're doing asynchronous stuff in a loop, which is always risky. See [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/q/750486/215552). – Heretic Monkey Feb 22 '19 at 18:34
  • Possible duplicate of [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Heretic Monkey Feb 22 '19 at 18:34

1 Answers1

3

All the images are being saved to a file named 'image 1.jpg' (10 times). You can confirm this by adding a console.log right before your call to axios.

I think the simplest solution is to change your loop from

for(image of images){
    const path1 = path.resolve(__dirname, 'images', `image ${count}.jpg`);

to

for (count = 0; count < images.length; count++) {
    image = images[i];
    const path1 = path.resolve(__dirname, 'images', `image ${count+1}.jpg`);
    // and any other references to count should be removed

Leftium
  • 16,497
  • 6
  • 64
  • 99
  • Yes it worked. But I don't understand what I was doing wrong? – Harshit Khanna Feb 23 '19 at 18:42
  • In your original code, `count++` changes the value of `count`, but this was not executed until after `path1` had been assigned (10 times to the same value). Because of the nature of async code, the order of execution is not axios(), then(), axios(), then()... but rather axios(), axios(), axios(),... then(), then(), then()... – Leftium Feb 23 '19 at 18:50