coder
coder

Reputation: 251

How to solve in IE11: Object doesn't support property or method 'padStart'

I have code that turns time intervals (sums and averages) into "hh:mm:ss" format just fine everywhere, except in IE 11, where I get this error:

SCRIPT438: Object doesn't support property or method 'padStart'

How can I rewrite this code so it would work?

var times = [3600000, 60000, 1000];

function formatTime(avg) {
    return times.map(function (t) {
        var value = Math.floor(avg / t);
        avg %= t;
        return value;
    }).map(function (v) {
        return v.toString().padStart(2, 0);
    }).join(':');
}

console.log(formatTime(32939000)); // 09:08:59

padStart(2, 0) is called in the last return statement. How can I make it work in IE11?

Upvotes: 2

Views: 7137

Answers (2)

jirassimok
jirassimok

Reputation: 4273

According MDN's documentation for the padStart, Internet Explorer does not support the function. However, they also provide a polyfill that will add padStart if it is missing. Just add the code block to the beginning of your program, and you'll have padStart in any browser.

// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
if (!String.prototype.padStart) {
    String.prototype.padStart = function padStart(targetLength, padString) {
        targetLength = targetLength >> 0; //truncate if number, or convert non-number to 0;
        padString = String(typeof padString !== 'undefined' ? padString : ' ');
        if (this.length >= targetLength) {
            return String(this);
        } else {
            targetLength = targetLength - this.length;
            if (targetLength > padString.length) {
                padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
            }
            return padString.slice(0, targetLength) + String(this);
        }
    };
}

(The preceding code is in the public domain, as per MDN's licensing page.)

Upvotes: 4

trincot
trincot

Reputation: 350996

For your specific case -- where you are dealing with time parts (hours, minutes, seconds), which have either 1 or 2 digits -- you can replace:

return v.toString().padStart(2, 0);

with:

return ("0" + v).slice(-2);

...and why not do that in the first iteration so you can avoid the additional map:

var times = [3600000, 60000, 1000];

function formatTime(avg) {
    return times.map(function (t) {
        var value = Math.floor(avg / t);
        avg %= t;
        return ("0" + value).slice(-2);
    }).join(':');
}

console.log(formatTime(32939000)); // 09:08:59

Another way is to first make the join, and then use \b\d\b as regular expression to spot the single digits and insert the missing zeroes with replace:

.join(':').replace(/\b\d\b/g, "0$&");

var times = [3600000, 60000, 1000];

function formatTime(avg) {
    return times.map(function (t) {
        var value = Math.floor(avg / t);
        avg %= t;
        return value;
    }).join(':').replace(/\b\d\b/g, "0$&");
}

console.log(formatTime(32939000)); // 09:08:59

Upvotes: 4

Related Questions