Suresh Atta
Suresh Atta

Reputation: 121998

Converting arraybuffer to string : Maximum call stack size exceeded

This is my code.

var xhr = new XMLHttpRequest();
xhr.open('GET',window.location.href, true);
xhr.responseType = "arraybuffer";
xhr.onload = function(event) {
 debugger;
 console.log(" coverting array buffer to string "); 
 alert(String.fromCharCode.apply(null, new Uint8Array(this.response)));
};
xhr.send();

That request is being made to a PDF URL which is around 3 MB in size. I have read a few threads with same error, Maximum call stack size exceeded, telling me that there must be some recursive call but I do not see any recursive call here. Can anyone help?

Upvotes: 26

Views: 22547

Answers (5)

Sven Döring
Sven Döring

Reputation: 4368

A little bit more optimized variant would be to utilize the available stack size instead of converting each character separately.

var text = '';
for(var i = 0; i < Math.ceil(bytes.length / 32768.0); i++) {
  text += String.fromCharCode.apply(null, bytes.slice(i * 32768, Math.min((i+1) * 32768, bytes.length)))
}

Upvotes: 1

Murali Krishna
Murali Krishna

Reputation: 167

Thank you so much Anthony O, you saved my 10 days work.
small modification in my scenario is:

Angular 7 :

/** Convert Uint8Array to string */

    private static arrayBufferToBase64( buffer: Uint8Array ) {
        var binary = '';
        var bytes = new Uint8Array( buffer );
        var len = bytes.byteLength;
        for (var i = 0; i < len; i++) {
            binary += String.fromCharCode( bytes[ i ] );
        }
        return  binary;
    }

Upvotes: 1

Anthony O.
Anthony O.

Reputation: 24367

I had the same problem and I finally used this code:

function _arrayBufferToBase64( buffer ) {
    var binary = '';
    var bytes = new Uint8Array( buffer );
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode( bytes[ i ] );
    }
    return window.btoa( binary );
}

Upvotes: 35

Igor Janenko
Igor Janenko

Reputation: 71

this.response.arrayBuffer()
              .then((buf) => {
                const uint8Array = new Uint8Array(buf);
                const data = uint8Array.reduce((acc, i) => acc += String.fromCharCode.apply(null, [i]), '');
                return data;
              })

Upvotes: 7

le_m
le_m

Reputation: 20228

The error is caused by a limitation in the number of function arguments. See "RangeError: Maximum call stack size exceeded" Why?

Instead of String.fromCharCode.apply(), use e. g. a TextEncoder. See Uint8Array to string in Javascript

Upvotes: 15

Related Questions