Reputation: 1439
I have come across similar questions, but none that quite fits my scenario.
In the code below, I am using the listContainers()
function from the dockerode Javascript library, to list the ids of my Docker containers. The snippet is adapted from one on the dockerode README. The listContainers
call works and the console.log line outputs the ids as expected. The problem is that I cannot push the container IDs into the array declared outside the function call - the result is that the array is still empty after the listContainers
call.
I am not very experienced with Javascript, but I think this problem is due to attempting the push inside the callback function. The problem is that the listContainers is asynchronous, so this means that //CONSOLE LOG #2
actually executes before //CONSOLE LOG #1
.
How can I capture the id values into the ids array outside the function call?
//Here is where I want to store my container ids.
var ids = [];
//Here is the dockerode call
dockerCli.listContainers(function(err, containers) {
containers.forEach(function(containerInfo) {
//log shows the correct id
console.log(containerInfo.Id);
//Here I try to save the container id to my array
ids.push(containerInfo.Id);
});
//CONSOLE LOG #1 Here I can see that the array has the correct values
console.log("IDs: "+ids.toString());
});
//CONSOLE LOG #2 Shows that the array is empty
console.log("IDs: "+ids.toString());
Upvotes: 0
Views: 504
Reputation: 1439
With the help of other commenters, I realised that the listContainers
call is asynchronous and there is simply no way to return a value from it.
So how to initialise and work with my ids
array? I created my own function that wraps the dockerode listContainers
call. This function then takes its own callback to do the work with the ids array. This allowed me to access the initialised ids array in my own callback, separating the functionality of processing the ids array from fetching the container list.
ids = [];
//Define my function that takes a callback function
//and just fetch the container ids
function getContainerJsonFromDocker(callback) {
dockerCli.listContainers(function(err, containers) {
containers.forEach(function(containerInfo) {
console.log(containerInfo.Id);
ids.push(containerInfo.Id);
});
return callback(ids);
});
}
//Now call my function, and pass it an anonymous callback
//The callback does the processing of the ids array
getContainerJsonFromDocker(function(ids) {
//This shows the array is initialised :)
console.log("IDs: " + ids.toString());
//Write my array to .json file
var outputFilename = 'data.json';
fs.writeFile(outputFilename, JSON.stringify(ids, null, 4),
function(err) {
if (err) {
console.log(err);
} else {
console.log("JSON saved to " + outputFilename);
}
});
});
Upvotes: 1
Reputation: 5264
you dont need to pass the global variable ids along with callback try this,
//Here is where I want to store my container ids.
var ids = [];
//Here is the dockerode call
dockerCli.listContainers(function(err, containers) {
containers.forEach(function(containerInfo) {
//log shows the correct id
console.log(containerInfo.Id);
//Here I try to save the container id to my array
ids.push(containerInfo.Id);
});
});
//Shows that the array is empty
console.log("IDs: "+ids.toString());
Upvotes: 0