0

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.

3 Answers 3

1

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");
});
Sign up to request clarification or add additional context in comments.

3 Comments

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 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/…
@Linus Still according to mozilla doc, object value are reference so you were right: developer.mozilla.org/en/JavaScript/Reference/…
1

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));

Comments

1

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");
});

3 Comments

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.
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!).
@LinusGThiel your right, it works either way. Fixed it

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.