I'm using Filepicker.io to store images. I'm trying to get the image's metadata using their filepicker.stat()
function. However, while it allows me to work with the metadata internally like so:
filepicker.stat(InkBlobs[i], { width: true, height: true }, function(metadata){ console.log(JSON.stringify(metadata)) });
I can't get the metadata out of that anonymous function. What I'd like to do is something like this:
for(i = 0; i < InkBlobs.length; i++)
{
filepicker.stat(InkBlobs[i], { width: true, height: true }, function(metadata){ InkBlobs[i].add(JSON.stringify(metadata)); });
}
This obviously doesn't work (the InkBlobs[i].add( ... )
) part, so how can I capture that metadata and include it with the other data located in the array? The array contents can each be JSON.stringify()
'd.
First, I assume that the callback receives metadata
as an argument; that's missing from the code in the question, but I will assume that below.
You can do basically what you wrote, you just have to manage i
slightly differently and have a place to store it. As this is JavaScript, you can just add your own property to the InkBlob
instances, but that's typically a bit dangerous (in case you conflict with something non-public, or they add something similar to the objects in the next release, etc.).
First let's deal with i
:
for(i = 0; i < InkBlobs.length; i++)
{
filepicker.stat(InkBlobs[i], { width: true, height: true }, makeCallback(i));
}
function makeCallback(index) {
return function(metadata){
InkBlobs[index].add(JSON.stringify(metadata));
// This bit ^^ is still theoretical
};
}
Now, instead of closing over i
, our callback closes over index
, which is the argument we passed to makeCallback
when we called it in the loop. Where i
changes before the callback occurs, index
does not.
You can also use ES5's bind
if the this
that the callback sees doesn't have to be controlled by stat
:
for(i = 0; i < InkBlobs.length; i++)
{
filepicker.stat(InkBlobs[i], { width: true, height: true }, function(index, metadata){
InkBlobs[index].add(JSON.stringify(metadata));
// This bit ^^ is still theoretical
}.bind(null, i));
}
Note that the argument i
we pass bind
shows up in front of any supplied by stat
(the first argument to bind
, null
in my example, is what sets this
during the callback).
I'll use bind
from here on out because it's more concise.
Now we have to store the metadata with the inkblobs. Here's one way:
var data = [];
var count = 0;
for(i = 0; i < InkBlobs.length; i++)
{
filepicker.stat(InkBlobs[i], { width: true, height: true }, function(index, metadata){
data[index] = {
blob: InkBlobs[index],
metadata: metadata // No reason to stringify it that I know of, but you could
};
++count;
if (count === InkBlobs.length) {
useTheNewArray();
}
}.bind(null, i));
}
Note that we wait to call useTheNewArray
until we've seen the callback for all blobs. Also note that we don't just push
to the new array, because they could arrive out of order (in theory). Of course, if the order doesn't matter, push
away and you don't need the count
variable anymore.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.