ImageTools.getImageFromBase64 not async safe

I am trying to set custom map markers for each one of a set of… map markers.
IconFile images come in the form of base64 data from the server; I then attempt to process them via ImageTools.getImageFromBase64 and save their image.path to an Observable string under each marker object, so I can use them as IconFile values.
It seems that no matter what I try, the image path returned by ImageTools.getImageFromBase64 seems to repeat itself for some of the markers. Not always in the same manner, so it seems there may be some race condition going on in there.

Even tried an ugly serialization attempt:

function processImage(ix)
{
    if (ix > markers.length - 1) {
        return;
    }

    ImageTools.getImageFromBase64(markers.getAt(ix).marker_image)
        .then(image => {
            markers.getAt(ix).marker.value = image.path;
            processImage(ix + 1);
        });
}

processImage(0);

Same effect.

Another attempt:

item.marker = Observable(item.marker_image).map(base64image => {
                let res = Observable(null);
                buf = Base64.decodeBuffer(base64image);
                FileSystem.writeBufferToFile(FileSystem.dataDirectory + '/map_marker_' + (ix + 1), buf)
                    .then(() => {
                        res.value = FileSystem.dataDirectory + '/map_marker_' + (ix + 1);
                        console.log(item.name);
                        console.log(res.value);
                    });
                return res;
            }).inner();

This time the file names seem ok (FileSystem does a better job of handling parallel calls), but the output is weird: on the first load the markers seem to keep their numbering (the images are actually blue rectangles with an index number written on them), but on subsequent refreshes the images get mixed up among the map markers.

Think there might also be a problem with how multiple markers are supported at this time.

Now, after a few refreshes, what seems to really bum the app out is zooming out (I am starting at level 15). Reloading markers at the base zoom level seems to more or less keep the right markers in place. As soon as I zoom out so that multiple markers are visible (they’re spread all over the globe), reloading the markers causes the images to shift (marker 1 gets image 3, 6, etc. in an irregular manner)

About your first post, the issue is not about async. I had the same problem, then looking through the forum I find the explanation:

«Images converted from Base-64 gets saved to a temporary location. The filenames are generated from timestamps with second resolution, which means that images overwrites each other if more than one is loaded within one second»

If you watch image.path with Monitor you will see that it happen that some files have the same name.

For this reason sometimes Base64 images seem to repeat, sometimes seem to work. Your second approach is the correct way to solve this issue until Fuse will generate filenames with a higher resolution or they will adopt an other way.

About the zooming issue I may not help you.

Your’re right :slight_smile: That’s exactly what happened.
Still, the issue now is that when more than one marker is visible on the screen, upon reloading the markers the custom icons get mixed among them.
Also, without doing anything, the current location, which is not customisable, “borrows” a marker icon from one of the markers. This happens on iOS preview, by the way. v0.35

Guys thank you so much for the detailed description and evaluation of this issue. My naive implementation of temp filenames had, as naive implementations tend to, bigger repercussions than I expected in the real world. A fix is on the way.

Don’t sweat it, Andreas.
The problem with mixing the marker icona if more than one appear on the screen may not be related to this, though. Make sure you guys take my last comment into consideration.