how to get browser language via script include or function call
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-21-2023 12:09 AM
gs.getSession().getLanguage() will retrieve current session pre-defined language but I want to get browser langugage/language code as kind of backup.
navigator.language || navigator.userLanguage seems like not working since it will show error of navigator is not defined.
also tried to create a new class of script include, but seems like not working either as following:
var BrowserLocaleUtil = Class.create();
BrowserLocaleUtil.prototype = {
initialize: function() {},
getBrowserLocale: function(request) {
var acceptLanguage = request.getHeader('Accept-Language');
if (acceptLanguage) {
var languageTag = acceptLanguage.split(',')[0];
return languageTag;
} else {
return 'en';
}
},
type: 'BrowserLocaleUtil'
};
and call in other script
var browserLocaleUtil = new BrowserLocaleUtil();
var browserLocale = browserLocaleUtil.getBrowserLocale(current.request);
Please help any JavaScript functions to retrieve the browser language code since there is potential missing from either service now user table or current session language set.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-21-2023 02:42 PM
Hi -O-,
Thank you so much for your details.
Everything works fine in background script, I can get locale using the following:
var acceptLanguage = GlideTransaction.get().getRequest().getHeader('Accept-Language');
var locale = acceptLanguage.split(',').shift();
gs.info(acceptLanguage);
=>
*** Script: en-US,en;q=0.9
But after I created global script include as attached screenshot
and call it in my application script include via:
var browserUtils = new global.BrowserUtils();
var expectedLocale = browserUtils.getBrowserLocale();
It shows error:
*** Script: Falied to get browser locale {"message":"Cannot convert null to an object.","rhinoException":{}}: no thrown error
Thanks in advance for your help!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-21-2023 06:06 PM
Hi János,
Thank you so much for your details.
When I run it in background script, everything works fine and I can get the following result:
1. running in Global scope with following:
var acceptLanguage= GlideTransaction.get().getRequest().getHeader('Accept-Language');
var languageTag = acceptLanguage.split(',').shift();
gs.log("acceptLanguage " + acceptLanguage);
=>
*** Script: acceptLanguage en-US,en;q=0.9
2. running in my application scope to call the global script include:
var utils = new global.BrowserUtils();
var language = utils.getBrowserLocale();
gs.info(language);
=>
en-US
But when I call in my application scope script include, it always fails with error
"message":"Cannot convert null to an object."
because GlideTransaction.get().getRequest() is always null
do you know the possible root cause?
Thank you so much in advance!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
11-22-2023 06:29 AM
What exactly triggers the scoped Script Include that calls the global Script Include?
I mean not every process/transaction in ServiceNow has an associated request.
Perhaps that is what is going on here.
In any case I would re-write the Script Include to account for the possibility that any of the methods returned invalid result, something like:
var BrowserLocaleUtil = Class.create();
BrowserLocaleUtil.pipe = function (rv, fn) {
return rv == null ? undefined : fn(rv);
};
BrowserLocaleUtil.prototype = {
'initialize': function () {
},
'getBrowserLocale': function () {
return this._getAcceptLanguage() || this._getDefaultLanguage();
},
'type': 'BrowserLocaleUtil',
'_getAcceptLanguage': function () {
return [
this._getGlideTransaction,
this._getGlideTransactionRequest,
this._getGlideTransactionRequestHeader('Accept-Language'),
this._getBaseLanguageTag
].reduce(BrowserLocaleUtil.pipe, {});
},
'_getBaseLanguageTag': function (data) {
return String(data).trim().split(/\s*,\s*/g).shift();
},
'_getDefaultLanguage': function () {
return '' + gs.getProperty('glide.sys.language', 'en');
},
'_getGlideTransaction': function () {
return GlideTransaction.get();
},
'_getGlideTransactionRequest': function (data) {
return data.getRequest();
},
'_getGlideTransactionRequestHeader': function (headerName) {
return function (data) {
return data.getHeader(headerName);
};
},
};
This is necessary because other than the above mentioned situation (there is no request in the transaction) even your script (but this one too) can be called from Scripts - Background both while running in global scope or in a private scope.