1

https://stackoverflow.com/a/1234337/1690081

shows that array.length = 0;will empty array but in my code it doesn't

here's an sample:

window.onload = draw;
window.onload = getFiles;
var namelist = [];
function draw(){
    // assing our canvas to element to a variable
    var canvas = document.getElementById("canvas1");
    // create html5 context object to enable draw methods
    var ctx = canvas.getContext('2d');

    var x = 10; // picture start cordinate
    var y = 10; // -------||---------
    var buffer = 10; // space between pictures
    for (i=0; i<namelist.length; i++){
        console.log(namelist[i])
        var image = document.createElement('img');
        image.src = namelist[i];
        canvas.appendChild(image);
        ctx.drawImage(image,x,y,50,50);
        x+=50+buffer;
    }
}
function getFiles(){
    namelist.length = 0;// empty name list
    var picturesFiles = document.getElementById('pictures')
    picturesFiles.addEventListener('change', function(event){
        var files = picturesFiles.files;

        for (i=0; i< files.length; i++){
            namelist.push(files[i].name);
            console.log(namelist)
        }
        draw();
    }, false);

}

after i call getFiles() second time. It doesn't remove the previous list, just appends to it. any idea why?

Community
  • 1
  • 1
Mihkel L.
  • 1,543
  • 1
  • 27
  • 42

4 Answers4

1

You should empty the array in the event handler, not getFiles which is only called once per pageload. It is actually doing nothing because the array is already empty when the page loads.

picturesFiles.addEventListener('change', function(event){
    namelist.length = 0; //empty it here
    var files = picturesFiles.files;

    for (i=0; i< files.length; i++){
        namelist.push(files[i].name);
        console.log(namelist)
    }
    draw();
}, false);

Another problem is that you cannot just set .src to the name of a file. That would make the request to your server for the file.

To really fix this, just push the file objects to the namelist:

namelist.push(files[i]);

Then as you process them in draw, create localized BLOB urls to show them:

var file = namelist[i];
var url = (window.URL || window.webkitURL).createObjectURL( file );
image.src = url;
Esailija
  • 138,174
  • 23
  • 272
  • 326
  • Although this works, it means that each time the function is called another event handler is added, so after the function has been called the second time, it will clear the array, fill it, then clear it again, then fill it again. If the function is called frequently, it will soon get quite slow. – Guffa Dec 07 '12 at 13:28
  • @Guffa `getFiles` is only called once, on window load... based on his code at least. When he says *when I call getFiles() again*, I am taking that to mean when he selects new files and triggers the event handler for the second time. If he really meant calling `getFiles()` again, the array would have been emptied with his original code. – Esailija Dec 07 '12 at 13:28
  • i meant triggering it for the second time yes. I can see why my wording could have made some confusion – Mihkel L. Dec 07 '12 at 13:44
  • If the function is only called from the load event, then the entire question is moot. Any array from the previous page doesn't exist any more, it's a completely new array object. – Guffa Dec 07 '12 at 13:46
  • @Guffa Yes, it was only cleared on page load. Now, you selected files, they got appended into the array. Then you selected new files, since the array wasn't cleared in the event handler, it just appended the new files to the old files gotten in first selection. There was no pageloads in-between this. – Esailija Dec 07 '12 at 13:50
  • when i impliment your suggestion it will show url value to be: `blob:null/96ede926-a192-42b8-90bb-d8b07d381edc` – Mihkel L. Dec 07 '12 at 14:29
  • @MihkelL. yes, that's the localized blob url. It looks like you are using `file:///` though, you should host a local web server. Look at this example and select an image file: http://jsfiddle.net/Svbb8/ – Esailija Dec 07 '12 at 14:31
  • the code must run in a chrome extension. i don't think that extensions run in a local server? – Mihkel L. Dec 07 '12 at 14:40
0

It looks like you're using namelist as a global variable. This would be easier (and would avoid needing to empty it at all) if you passed the new array out of the function as a return value.

ie:

function getFiles() {
    var newNameList = [];
    ..... //push entries here.
    return newNameList;
}

... and then populate namelist from the return value where you call it:

namelist = getFiles();

However, to answer the question that was actually asked:

Instead of setting the length to zero, you can also reset an array simply by setting it to a new array:

namelist = [];

You haven't shown us how you're 'pushing' entries to the list, but I suspect that the end result is that namelist is being generated as a generic object rather than an array object. If this is the case, then setting .length=0 will simply add a property to the object named length with a value of 0. The length property in the way you're using it only applies to Array objects.

Hope that helps.

SDC
  • 14,192
  • 2
  • 35
  • 48
0

If you are using non-numeric indexes then the array will not clear. "...whenever the length property is changed, every property whose name is an array index whose value is not smaller than the new length is automatically deleted"

Test:
var arr = [];
arr['this'] = 'that';
arr.length = 0;
console.log(arr);
//output ['this':'that']

var arr = [];
arr[0] = 'that';
arr.length = 0;
console.log(arr);
//output []
Tim Joyce
  • 4,487
  • 5
  • 34
  • 50
0

There is nothing wrong with how you empty the array, so there has to be something else that is wrong with your code.

This works fine, the array doesn't contain the previous items the second time:

var namelist = [];

function draw() {
    alert(namelist.join(', '));
}

function getFiles() {
    namelist.length = 0; // empty name list
    namelist.push('asdf');
    namelist.push('qwerty');
    namelist.push('123');
    draw();
}

getFiles();
getFiles();

Demo: http://jsfiddle.net/Guffa/76RuX/

Edit:

Seeing your actual code, the problem comes from the use of a callback method to populate the array. Every time that you call the function, you will add another event handler, so after you have called the function the seccond time, it will call two event handlers that will each add all the items to the array.

Only add the event handler once.

Community
  • 1
  • 1
Guffa
  • 687,336
  • 108
  • 737
  • 1,005