bool3max
bool3max

Reputation: 2865

Downloading image doesn't work: NodeJS

I've written a little function in Node for downloading an image from a server and saving it on my server, but it doesn't work. The image file is created, but it seems to be corrupt, here's the function:

function d() {
    var data = [
        {
            img: "http://wow.zamimg.com/images/hearthstone/cards/enus/original/OG_134.png",
            cardId: "yogg"
        },
        {
            img: "http://wow.zamimg.com/images/hearthstone/cards/enus/original/HERO_07.png",
            cardId: "nzoth"
        }
    ];
    for(var card of data) {
        if("img" in card) {
            var img = require('fs').createWriteStream("./public/assets/pics/" + card.cardId + ".png");
            require("http").get(card.img, (res) => {
                res.pipe(img);
            });
        }
    }
}

What am I doing wrong?

Upvotes: 0

Views: 1248

Answers (2)

luispa
luispa

Reputation: 323

Use this:

var fs = require('fs'),
    request = require('request');

var download = function(uri, filename, callback){
  request.head(uri, function(err, res, body){
    console.log('content-type:', res.headers['content-type']);
    console.log('content-length:', res.headers['content-length']);

    request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
  });
};

download('https://www.THE_URL.com/image.png', 'THE_NAME.png', function(){
  console.log('Image saved!');
});

Upvotes: 1

Niklas Ingholt
Niklas Ingholt

Reputation: 477

The problem is that your process exits before the downloads are finished. The http.get functions runs in parallel so you need to handle that in some way. You can use the async module to do that.

function d() {
var data = [
    {
        img: "http://wow.zamimg.com/images/hearthstone/cards/enus/original/OG_134.png",
        cardId: "yogg"
    },
    {
        img: "http://wow.zamimg.com/images/hearthstone/cards/enus/original/HERO_07.png",
        cardId: "nzoth"
    }
];
var async = require('async')
async.each(data, (card, next) => {
    if("img" in card) {
        var img = require('fs').createWriteStream(card.cardId + ".png");
          require("http").get(card.img, (res) => {
              res.pipe(img).on('end', next)
          });
    }
}
, () => {
  console.log(done)
})
}

Upvotes: 1

Related Questions