Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #35238 > unrolled thread
| Started by | Andrew Poulos <ap_prog@hotmail.com> |
|---|---|
| First post | 2018-06-19 19:44 +1000 |
| Last post | 2018-06-21 15:16 -0700 |
| Articles | 6 — 5 participants |
Back to article view | Back to comp.lang.javascript
Array of Files to array of data url Andrew Poulos <ap_prog@hotmail.com> - 2018-06-19 19:44 +1000
Re: Array of Files to array of data url Jake Jarvis <pig_in_shoes@yahoo.com> - 2018-06-19 12:28 +0200
Re: Array of Files to array of data url Jon Ribbens <jon+usenet@unequivocal.eu> - 2018-06-19 14:47 +0000
Re: Array of Files to array of data url Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2018-06-20 21:47 +0200
Re: Array of Files to array of data url Andrew Poulos <ap_prog@hotmail.com> - 2018-06-21 15:33 +1000
Re: Array of Files to array of data url "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2018-06-21 15:16 -0700
| From | Andrew Poulos <ap_prog@hotmail.com> |
|---|---|
| Date | 2018-06-19 19:44 +1000 |
| Subject | Array of Files to array of data url |
| Message-ID | <8dGdnZA1WKvpTbXGnZ2dnUU7-e3NnZ2d@westnet.com.au> |
I have this array
var files = [File, File, null, File];
and I need to create a new array with the data from each File (or null
if it's null).
I tried
var newarr = files.map(function(el){
if (el === null) return null;
var reader = new FileReader();
reader.addEventListener("load", function () {
return reader.result;
}, false);
reader.readAsDataURL(el);
});
but the array only ever gets populated with null. How can this be done?
Andrew Poulos
[toc] | [next] | [standalone]
| From | Jake Jarvis <pig_in_shoes@yahoo.com> |
|---|---|
| Date | 2018-06-19 12:28 +0200 |
| Message-ID | <pgalt3$hdf$1@dont-email.me> |
| In reply to | #35238 |
Am 19.06.2018 um 11:44 schrieb Andrew Poulos:
> I have this array
>
> var files = [File, File, null, File];
>
> and I need to create a new array with the data from each File (or null
> if it's null).
>
> I tried
>
> var newarr = files.map(function(el){
> if (el === null) return null;
>
> var reader = new FileReader();
>
> reader.addEventListener("load", function () {
> return reader.result;
> }, false);
>
> reader.readAsDataURL(el);
> });
>
> but the array only ever gets populated with null. How can this be done?
>
> Andrew Poulos
File API is asynchronous. ("Don't call us, we'll call you")
No idea what the big picture is, maybe those new Promise things can help.
[toc] | [prev] | [next] | [standalone]
| From | Jon Ribbens <jon+usenet@unequivocal.eu> |
|---|---|
| Date | 2018-06-19 14:47 +0000 |
| Message-ID | <slrnpii5sq.3qm.jon+usenet@sable.unequivocal.eu> |
| In reply to | #35238 |
On 2018-06-19, Andrew Poulos <ap_prog@hotmail.com> wrote:
> I have this array
>
> var files = [File, File, null, File];
>
> and I need to create a new array with the data from each File (or null
> if it's null).
>
> I tried
>
> var newarr = files.map(function(el){
> if (el === null) return null;
>
> var reader = new FileReader();
>
> reader.addEventListener("load", function () {
> return reader.result;
> }, false);
>
> reader.readAsDataURL(el);
> });
>
> but the array only ever gets populated with null. How can this be done?
You're not returning a value from your map function, except when the
element is null. You'd need to do something like:
function loadAll (files, complete) {
var results = []
var nResults = 0
var expected = 0
files.forEach(function () { expected += 1 })
function received (result, index) {
results[index] = result
nResults += 1
if (nResults >= expected) complete(results)
}
files.forEach(function (file, index) {
if (file === null) return received(null, index)
var reader = new FileReader()
reader.onload = function () { received(reader.result, index) }
reader.onabort = reader.onerror = function (event) {
received(event.type, index)
}
reader.readAsDataURL(file)
})
}
and then do:
var files = [File, File, null, File]
loadAll(files, function (results) {
// do something with the loaded files, checking for aborts/errors also
})
Note I haven't tested this code.
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2018-06-20 21:47 +0200 |
| Message-ID | <d6b53130-1df1-d8fc-0ac6-3949f37bfe54@PointedEars.de> |
| In reply to | #35238 |
Andrew Poulos wrote:
> var newarr = files.map(function(el){
> if (el === null) return null;
>
> var reader = new FileReader();
>
> reader.addEventListener("load", function () {
^^^^^^^^^^^^^
> return reader.result;
> }, false);
>
> reader.readAsDataURL(el);
> });
>
> but the array only ever gets populated with null. How can this be done?
It is the (unfortunately common) mistake of expecting something to work
synchronously when it *clearly* does not. With minimum changes, untested:
var newarr = []:
var loaded = 0;
function allLoaded ()
{
… newarr …
}
files
.forEach(function (el, i, a) {
/* consider: if (!el) */
if (el === null) return;
var reader = new FileReader();
reader.addEventListener("load", function () {
newarr[i] = reader.result;
++loaded;
if (loaded === a.length) allLoaded();
}, false);
reader.readAsDataURL(el);
});
If you can live with the fact that the indexes do not match, you should
filter the array so that the callback is not called for null elements in
the first place and call Array.prototype.push() instead.
If you want to process the results in any case (whether successful or not),
you have to handle the “error” event and increase in its listener the
“loaded” counter as well (you should rename it then).
PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f806at$ail$1$8300dec7@news.demon.co.uk>
[toc] | [prev] | [next] | [standalone]
| From | Andrew Poulos <ap_prog@hotmail.com> |
|---|---|
| Date | 2018-06-21 15:33 +1000 |
| Message-ID | <N4OdnS1AXoc3pbbGnZ2dnUU7-bfNnZ2d@westnet.com.au> |
| In reply to | #35254 |
On 21/06/2018 5:47 AM, Thomas 'PointedEars' Lahn wrote:
> Andrew Poulos wrote:
>> var newarr = files.map(function(el){
>> if (el === null) return null;
>>
>> var reader = new FileReader();
>>
>> reader.addEventListener("load", function () {
> ^^^^^^^^^^^^^
>> return reader.result;
>> }, false);
>>
>> reader.readAsDataURL(el);
>> });
>>
>> but the array only ever gets populated with null. How can this be done?
>
> It is the (unfortunately common) mistake of expecting something to work
> synchronously when it *clearly* does not. With minimum changes, untested:
When things fail (and I miss the forest for the trees) I run out of
options :-(
> var newarr = []:
> var loaded = 0;
>
> function allLoaded ()
> {
> … newarr …
> }
>
> files
> .forEach(function (el, i, a) {
> /* consider: if (!el) */
> if (el === null) return;
>
> var reader = new FileReader();
>
> reader.addEventListener("load", function () {
> newarr[i] = reader.result;
> ++loaded;
> if (loaded === a.length) allLoaded();
> }, false);
>
> reader.readAsDataURL(el);
> });
>
> If you can live with the fact that the indexes do not match, you should
> filter the array so that the callback is not called for null elements in
> the first place and call Array.prototype.push() instead.
>
> If you want to process the results in any case (whether successful or not),
> you have to handle the “error” event and increase in its listener the
> “loaded” counter as well (you should rename it then).
Thanks, it's similar to what glathoud suggested.
Andrew Poulos
[toc] | [prev] | [next] | [standalone]
| From | "Michael Haufe (TNO)" <tno@thenewobjective.com> |
|---|---|
| Date | 2018-06-21 15:16 -0700 |
| Message-ID | <02d04815-0dc7-4633-ab3a-1434d1fe6601@googlegroups.com> |
| In reply to | #35238 |
On Tuesday, June 19, 2018 at 4:44:32 AM UTC-5, Andrew Poulos wrote:
> I have this array
>
> var files = [File, File, null, File];
>
> and I need to create a new array with the data from each File (or null
> if it's null).
>
> I tried
>
> var newarr = files.map(function(el){
> if (el === null) return null;
>
> var reader = new FileReader();
>
> reader.addEventListener("load", function () {
> return reader.result;
> }, false);
>
> reader.readAsDataURL(el);
> });
>
> but the array only ever gets populated with null. How can this be done?
To add to the other examples given:
<script type="text/typescript">
function fileToDataUri(file: File): Promise<string> {
return new Promise<string>((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
//...
Promise.all(
files.map(fileToDataUri)
).then(results => {
...
}).catch(errors => {
...
})
</script>
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.javascript
csiph-web