Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am using node.js "async" module and need to use the "map" method.
Basically I have an array that contains other arrays. The inner arrays contains 2 elements, a type and an image filename.

var arr0 = [];
var arr1 = ["type1", "image1.jpg"];
jsonArr.push(obj1);
var arr2 = ["type2", "image2.jpg"];
jsonArr.push(obj2);

For each inner array, I want to get the base64 encoding of the image identified by the filename and add this encoding string as the third element of the array.

I'm doing something like this:

var fs = require("fs");
var async = require("async");

function getImageEncoding(arr, callback){
    console.log("getEncoding:" + arr + "\n");

    // Get image filename
    image = arr[1];

    // Read file and get base64 encoding
    fs.readFile(image, function(err, original_data){
    var base64Image = original_data.toString('base64');
    console.log("test:" + base64Image + "\n");

        // Modify current arr by appendingthe base64 encoding of the image
        callback(null, arr.push(base64Image));
    });
}

async.map(arr0, getImageEncoding, function(err, results){
console.log("in async.map: " + results + "\n");
});

I know the arr.push(base64Image) stuff is the thing that is not correct, but I cannot figure out how to return the modified element.

In map(arr, iterator, callback) documentation, it is specified:

"The iterator is called with an item from the array and a callback for when it has finished processing."

The thing is I cannot figure out how to feed the callback with the new arrays.

share|improve this question
add comment

3 Answers

up vote 1 down vote accepted

This doesn't work because callback in getImageEncoding is called with the return value of arr.push (which is 1), not arr after arr.push, which is what you want.

function getImageEncoding(arr, callback){
    console.log("getEncoding:" + arr + "\n");

    // Get image filename
    image = arr[1];

    // Read file and get base64 encoding
    fs.readFile(image, function(err, original_data){
    var base64Image = original_data.toString('base64');
    console.log("test:" + base64Image + "\n");

        // Modify current arr by appendingthe base64 encoding of the image
        arr.push(base64Image);
        callback(err, arr);
    });
}

async.map(arr0, getImageEncoding, function(err, results){
console.log("in async.map: " + results + "\n");
});
share|improve this answer
    
thanks, that works perfectly –  Luc Mar 1 '12 at 15:20
    
But it's not true that parameters are passed by copy, they are indeed passed by reference. The code above will modify the original array (i.e. arr0[0] === results[0] in the final callback). –  Linus G Thiel Mar 1 '12 at 15:26
    
@Linus I thought === was not a reference comparison operator but a comparison without conversion one. I did not found reference on v8 and node.js about this but in mozilla doc I found this: developer.mozilla.org/en/JavaScript/Reference/Operators/… –  Nicocube Mar 1 '12 at 15:51
    
@Linus Still according to mozilla doc, object value are reference so you were right: developer.mozilla.org/en/JavaScript/Reference/… –  Nicocube Mar 1 '12 at 15:55
add comment

The problem is that you execute your callback with the return value of arr.push as your result, where you really want an array as the result. Just use concat instead:

callback(null, arr.concat(base64Image));
share|improve this answer
add comment

You map it properly. You need to use the callback in the iterator, Try the documentation of after

var fs = require("fs");
var after = require("after");

function getImageEncoding(tuple, callback){
    fs.readFile(arr[1], function(err, data){
        if (err) return callback(err)
        callback(null, tuple.concat(data.toString('base64'))
    });
}

after.map(arr0, getImageEncoding, function(err, results){
    console.log("in after.map: " + results + "\n");
});
share|improve this answer
    
While after looks cool, the asker's problem seems to be that he wants the results to consist of the original arrays, but with base64 data as well. –  Linus G Thiel Mar 1 '12 at 15:16
1  
@LinusGThiel fixed :) –  Raynos Mar 1 '12 at 16:30
    
Nice! Do you really have to pass an array to concat, though? Might be a browser thing I'm not familiar with, but it happily concats with plain parameters (yes, it's variadic too boot!). –  Linus G Thiel Mar 1 '12 at 17:30
1  
@LinusGThiel your right, it works either way. Fixed it –  Raynos Mar 1 '12 at 17:34
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.