2

I have some code similar to the following for downloading a binary file. My goal is to convert it to a base64 data URI while supporting older browsers that might not know about ArrayBuffer. Right now, the code seems to work well enough.

function download (url) {
    'use strict';
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'arraybuffer';
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            var mime = xhr.getResponseHeader('Content-Type');
            var base64;
            if (oldIE) {
                var rawBytes = ieConvert(xhr.responseBody);
                base64 = encodeString64(rawBytes);
            } else if (xhr.response instanceof ArrayBuffer) {
                var payload = new Uint8Array(xhr.response);
                for (var i = 0, buffer = ''; i < payload.length; i++) {
                    buffer += String.fromCharCode(payload[i]);
                }
                base64 = window.btoa(buffer);
            } else if (xhr.response instanceof String) {
                base64 = encodeString64(xhr.response);
            }
            return 'data:' + mime + ';base64,' + base64;
        } else if (xhr.readyState === 4) {
            throw "Failed.";
        }
    };
    xhr.send();
}

My problem is that when I use Google Closure Compiler I get a type warning. Obviously, it's because I used instanceof String, but instanceof string doesn't work because the object name should be capitalized.

WARNING - actual parameter 1 of encodeString64 does not match formal parameter
found   : String
required: string
                    base64 = encodeString64(xhr.response);
                                            ^
0 error(s), 1 warning(s), 85.22012578616352 typed

Any idea how to get rid of this warning?

  • 1
    Where is encodeString64() defined? Can you post that code? – Peter Bratton Sep 26 '12 at 16:46
  • It's really nothing special, and for all intents and purposes is functionally identical to the [this answer](http://stackoverflow.com/a/246813/1700830). –  Sep 26 '12 at 17:03

1 Answers1

2
base64 = encodeString64(String(xhr.response));

Try this out in order to understand the difference:

<script>
x = new String("hello");
alert(typeof x); //prints Object (this is a String object)

x = String("hello"); //or x = "hello";
alert(typeof x); //prints string (this is string with small s - similar to running toString() on a JS object)
</script>
raidenace
  • 12,789
  • 1
  • 32
  • 35
  • `string` types can be used any place a `String` is required, but not the other way around. That's why you got the warning. You could also use `xhr.response.toString()`. – Chad Killingsworth Sep 26 '12 at 19:53