Illegal Invocation while trying to use decodeBase64() formatter on client

I’m not sure if I’m doing something incorrectly or if something changed from the details provided here

Here’s the code that should convert the base64 data

Here’s the error message I receive
image

Any ideas on how to correct it?

Mentioning @patrick for visibility.

ChatGPT to the rescue. This code worked.

<script>
        dmx.Formatters('string', {
        encodeBase64: function(str) {
        return Buffer.from(str).toString('base64');
        },
        decodeBase64: function(str) {
        return Buffer.from(str, 'base64').toString();
        }
        });
    </script>

The solution you give only works in a NodeJS environment, the Buffer is not available within the browser. In the browser you can use atob and btoa functions (https://developer.mozilla.org/en-US/docs/Web/API/atob).

Thanks, Patrick. The error mentioned in the original post happened while using atob and btoa functions.

In what kind of environment is the code running? The Illegal Invocation error is when a function has lost its context, the internal this keyword is not bound. Depending on how the method is called the context can change. Instead of calling atob(str) directly use window.atob(str). If you are in a node environment (like an electron app) you can use the Buffer methods.

It’s a Capacitor app that’s currently being developed/tested in browser, but will ultimately move to Electron, Android, iOS.

If using the custom formatter you suggested. Would window go with the btoa and atob?

dmx.Formatters('string', {
    encodeBase64: btoa,
    decodeBase64: atob
});

Like this?

dmx.Formatters('string', {
    encodeBase64: window.btoa,
    decodeBase64: window.atob
});

Better is

dmx.Formatters('string', {
    encodeBase64: (str) => window.btoa(str),
    decodeBase64: (str) => window.atob(str)
});

or

dmx.Formatters('string', {
    encodeBase64: window.btoa.bind(window),
    decodeBase64: window.atob.bind(window)
});
1 Like

Both of those throw this error.

dmxAppConnect.js:7 DOMException: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
    at http://localhost:60359/dmxAppConnect/dmxAppConnect.js:7:28375
    at http://localhost:60359/dmxAppConnect/dmxAppConnect.js:7:28306
    at http://localhost:60359/dmxAppConnect/dmxAppConnect.js:7:25666
    at dmx.parse (http://localhost:60359/dmxAppConnect/dmxAppConnect.js:7:25744)
    at n.$updateBindings (http://localhost:60359/dmxAppConnect/dmxAppConnect.js:7:34930)
    at n.$update (http://localhost:60359/dmxAppConnect/dmxAppConnect.js:7:34484)
    at http://localhost:60359/dmxAppConnect/dmxAppConnect.js:7:34630
    at Array.forEach (<anonymous>)
    at n.$update (http://localhost:60359/dmxAppConnect/dmxAppConnect.js:7:34607)
    at http://localhost:60359/dmxAppConnect/dmxAppConnect.js:7:11010

What exactly was the encoded string, did it contain some unicode characters or was it a binary string?

It’s the html body content from an email message.

Here’s an example.
PGJvZHkgc3R5bGU9InRleHQtYWxpZ246bGVmdDsiIGRpcj0ibHRyIj4NCg0KPCEtLVtpZiBtc29dPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCmJvZHksIHRhYmxlLCB0ZCwgdGgsIGgxLCBoMiwgaDMge2ZvbnQtZmFtaWx5OiBIZWx2ZXRpY2EsIEFyaWFsLCBzYW5zLXNlcmlmICFpbXBvcnRhbnQ7fQ0KPC9zdHlsZT4NCjwhW2VuZGlmXS0tPg0KDQoNCiAgICANCiAgICA8ZGl2Pg0KDQogIDxkaXY-PC9kaXY-DQoNCiAgICA8ZGl2IHN0eWxlPSJtYXJnaW4tYm90dG9tOjI1cHg7Ij4NCiAgPHRhYmxlIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iMCIgYm9yZGVyPSIwIj4NCiAgICA8dGJvZHk-PHRyPg0KICAgICAgPHRkIHN0eWxlPSJ2ZXJ0aWNhbC1hbGlnbjp0b3A7d2lkdGg6NTVweDsiPg0KICAgICAgICA8aW1nIHNyYz0iaHR0cHM6Ly9jb21tdW5pdHkud2FwcGxlci5pby91c2VyX2F2YXRhci9jb21tdW5pdHkud2FwcGxlci5pby9wYXRyaWNrLzQ1LzIwNTgzXzIucG5nIiB0aXRsZT0icGF0cmljayIgd2lkdGg9IjQ1IiBoZWlnaHQ9IjQ1Ij4NCiAgICAgIDwvdGQ-DQogICAgICA8dGQ-DQogICAgICAgICAgPGEgaHJlZj0iaHR0cHM6Ly9jb21tdW5pdHkud2FwcGxlci5pby91L3BhdHJpY2siIHRhcmdldD0iX2JsYW5rIiBzdHlsZT0iY29sb3I6IzAwNjY5OTs7IGZvbnQtc2l6ZToxM3B4O2ZvbnQtZmFtaWx5OidsdWNpZGEgZ3JhbmRlJyx0YWhvbWEsdmVyZGFuYSxhcmlhbCxzYW5zLXNlcmlmO3RleHQtZGVjb3JhdGlvbjpub25lO2ZvbnQtd2VpZ2h0OmJvbGQ7IHRleHQtZGVjb3JhdGlvbjogbm9uZTsgZm9udC13ZWlnaHQ6IGJvbGQ7IGNvbG9yOiAjMDA2Njk5OyI-cGF0cmljazwvYT4NCiAgICAgICAgICA8c3BhbiBzdHlsZT0iZm9udC1zaXplOjEzcHg7Zm9udC1mYW1pbHk6J2x1Y2lkYSBncmFuZGUnLHRhaG9tYSx2ZXJkYW5hLGFyaWFsLHNhbnMtc2VyaWY7dGV4dC1kZWNvcmF0aW9uOm5vbmU7bWFyZ2luLWxlZnQ6NXB4O2NvbG9yOiAjOTk5OyI-VGVhbTwvc3Bhbj4NCiAgICAgICAgPGJyPg0KICAgICAgICA8c3BhbiBzdHlsZT0idGV4dC1hbGlnbjpyaWdodDtjb2xvcjojOTk5OTk5O3BhZGRpbmctcmlnaHQ6NXB4O2ZvbnQtZmFtaWx5OidsdWNpZGEgZ3JhbmRlJyx0YWhvbWEsdmVyZGFuYSxhcmlhbCxzYW5zLXNlcmlmO2ZvbnQtc2l6ZToxMXB4Ij5KdWx5IDE3PC9zcGFuPg0KICAgICAgPC90ZD4NCiAgICA8L3RyPg0KICA8L3Rib2R5PjwvdGFibGU-DQogIDxkaXYgc3R5bGU9InBhZGRpbmctdG9wOjVweDsiPjxwIHN0eWxlPSJtYXJnaW4tdG9wOjA7IGJvcmRlcjogMDsiPkluIHdoYXQga2luZCBvZiBlbnZpcm9ubWVudCBpcyB0aGUgY29kZSBydW5uaW5nPyBUaGUgPGNvZGUgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNmMWYxZmY7IHBhZGRpbmc6IDJweCA1cHg7Ij5JbGxlZ2FsIEludm9jYXRpb248L2NvZGU-IGVycm9yIGlzIHdoZW4gYSBmdW5jdGlvbiBoYXMgbG9zdCBpdHMgY29udGV4dCwgdGhlIGludGVybmFsIDxjb2RlIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiAjZjFmMWZmOyBwYWRkaW5nOiAycHggNXB4OyI-dGhpczwvY29kZT4ga2V5d29yZCBpcyBub3QgYm91bmQuIERlcGVuZGluZyBvbiBob3cgdGhlIG1ldGhvZCBpcyBjYWxsZWQgdGhlIGNvbnRleHQgY2FuIGNoYW5nZS4gSW5zdGVhZCBvZiBjYWxsaW5nIDxjb2RlIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiAjZjFmMWZmOyBwYWRkaW5nOiAycHggNXB4OyI-YXRvYihzdHIpPC9jb2RlPiBkaXJlY3RseSB1c2UgPGNvZGUgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNmMWYxZmY7IHBhZGRpbmc6IDJweCA1cHg7Ij53aW5kb3cuYXRvYihzdHIpPC9jb2RlPi4gSWYgeW91IGFyZSBpbiBhIG5vZGUgZW52aXJvbm1lbnQgKGxpa2UgYW4gZWxlY3Ryb24gYXBwKSB5b3UgY2FuIHVzZSB0aGUgQnVmZmVyIG1ldGhvZHMuPC9wPjwvZGl2Pg0KPC9kaXY-DQoNCg0KDQoNCg0KDQogIDxkaXYgc3R5bGU9ImNvbG9yOiM2NjY7Ij48aHIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNkZGQ7IGhlaWdodDogMXB4OyBib3JkZXI6IDFweDs7IGJhY2tncm91bmQtY29sb3I6ICNkZGQ7IGhlaWdodDogMXB4OyBib3JkZXI6IDFweDsiPg0KPHA-PGEgaHJlZj0iaHR0cHM6Ly9jb21tdW5pdHkud2FwcGxlci5pby90L2lsbGVnYWwtaW52b2NhdGlvbi13aGlsZS10cnlpbmctdG8tdXNlLWRlY29kZWJhc2U2NC1mb3JtYXR0ZXItb24tY2xpZW50LzUwOTMyLzUiIHN0eWxlPSJmb250LXdlaWdodDogbm9ybWFsOzsgdGV4dC1kZWNvcmF0aW9uOiBub25lOyBmb250LXdlaWdodDogYm9sZDsgY29sb3I6ICMwMDY2OTk7OyBiYWNrZ3JvdW5kLWNvbG9yOiAjMkY3MEFDOyBjb2xvcjogI0ZGRkZGRjsgYm9yZGVyLXRvcDogNHB4IHNvbGlkICMyRjcwQUM7IGJvcmRlci1yaWdodDogNnB4IHNvbGlkICMyRjcwQUM7IGJvcmRlci1ib3R0b206IDRweCBzb2xpZCAjMkY3MEFDOyBib3JkZXItbGVmdDogNnB4IHNvbGlkICMyRjcwQUM7IGRpc3BsYXk6IGlubGluZS1ibG9jazsgZm9udC13ZWlnaHQ6IGJvbGQ7Ij5WaXNpdCBUb3BpYzwvYT4gb3IgcmVwbHkgdG8gdGhpcyBlbWFpbCB0byByZXNwb25kLjwvcD48L2Rpdj4NCiAgPGRpdiBzdHlsZT0iY29sb3I6IzY2NjsiPjxwPlRvIHVuc3Vic2NyaWJlIGZyb20gdGhlc2UgZW1haWxzLCA8YSBocmVmPSJodHRwczovL2NvbW11bml0eS53YXBwbGVyLmlvL2VtYWlsL3Vuc3Vic2NyaWJlLzAxNGY3ZjE3Njk0YjI0MTBmYWU3NzY5OGJhMjNhY2I3Y2NiNzE5ZWU3YTBjYzU5NjVkNmJhNTExOGQzZmNkNjQiIHN0eWxlPSJ0ZXh0LWRlY29yYXRpb246IG5vbmU7IGZvbnQtd2VpZ2h0OiBib2xkOyBjb2xvcjogIzAwNjY5OTs7IGNvbG9yOiM2NjY7Ij5jbGljayBoZXJlPC9hPi48L3A-PC9kaXY-DQoNCjwvZGl2Pg0KDQo8ZGl2IGl0ZW1zY29wZT0iIiBpdGVtdHlwZT0iaHR0cDovL3NjaGVtYS5vcmcvRW1haWxNZXNzYWdlIiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgPGRpdiBpdGVtcHJvcD0iYWN0aW9uIiBpdGVtc2NvcGU9IiIgaXRlbXR5cGU9Imh0dHA6Ly9zY2hlbWEub3JnL1ZpZXdBY3Rpb24iPg0KICAgIDxsaW5rIGl0ZW1wcm9wPSJ1cmwiIGhyZWY9Imh0dHBzOi8vY29tbXVuaXR5LndhcHBsZXIuaW8vdC9pbGxlZ2FsLWludm9jYXRpb24td2hpbGUtdHJ5aW5nLXRvLXVzZS1kZWNvZGViYXNlNjQtZm9ybWF0dGVyLW9uLWNsaWVudC81MDkzMi81Ij4NCiAgICA8bWV0YSBpdGVtcHJvcD0ibmFtZSIgY29udGVudD0iUmVhZCBmdWxsIHRvcGljIj4NCiAgPC9kaXY-DQo8L2Rpdj4NCg0KDQoNCjwhLS0gcHJldmVudCBHbWFpbCBvbiBpT1MgZm9udCBzaXplIG1hbmlwdWxhdGlvbiAtLT4NCjxkaXYgc3R5bGU9ImRpc3BsYXk6bm9uZTt3aGl0ZS1zcGFjZTpub3dyYXA7Zm9udDoxNXB4IGNvdXJpZXI7bGluZS1oZWlnaHQ6MCI-Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsNCiAgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDs8L2Rpdj4NCg0KDQoNCjwvYm9keT4=

It seems that the string is Base64Url encoded, it is a variant of Base64 that is safe to use in urls.

Here a Base64Url encode/decode:

dmx.Formatters('string', {
    encodeBase64Url: (str) => window.btoa(str).replace(/+/,g, '-').replace(/\//g, '_'),
    decodeBase64Url: (str) => window.atob(str.replace(/-/g, '+').replace(/_/g, '/')
});
1 Like