[ALOY-980] Alloy: Builtin moment.js causes exception on device if language is not EN
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | Low |
Status | Closed |
Resolution | Invalid |
Resolution Date | 2014-04-04T20:55:58.000+0000 |
Affected Version/s | Alloy 1.3.1 |
Fix Version/s | n/a |
Components | n/a |
Labels | alloy, android, community, ios, moment.js |
Reporter | Stefan Schüller |
Assignee | Unknown |
Created | 2014-04-02T12:40:50.000+0000 |
Updated | 2018-03-07T22:28:26.000+0000 |
Description
Steps to reproduce
1. Create new Alloy project. Default Alloy Project
2. edit index.js controller and add the following to the end:
moment = require('alloy/moment');
var test = moment().format('YYYY-MM-DD HH:mm:ss');
console.log(test);
3. Change language on IOS device to anything other than english (I used German)
4. Debug on device.
5. Execution will halt with:
Thread [kroll$1] (Suspended (exception at line 72 in moment.js))
getLangDefinition(key) [moment.js:72]
[Eval script] [moment.js:663]
[Eval script] [moment.js:964]
[Eval script] [moment.js:1]
[Eval script] [moment.js:1]
Controller() [index.js:7]
[Eval script] [alloy.js:231]
[Top-level script] [app.js:3]
Problem code is missing language files:
function getLangDefinition(key) {
if (!key) return moment.fn._lang;
if (!languages[key] && hasModule) try {
>>>> loadLang(key, require("alloy/moment/lang/" + key)); <<<<
} catch (e) {
return moment.fn._lang;
}
return languages[key];
}
Moving this ticket to engineering as I can reproduce this issue on iPhone 5s with Italian language.
I just tested the [advanced/moment.js sample app](https://github.com/appcelerator/alloy/tree/master/test/apps/advanced/momentjs) on my iPad, setting the iPad to Spanish. The app works fine. I suspect something with your code. Could you please compare your code to the sample app to confirm the problem is not with your code. Looking at the sample app, you must include:
Marking invalid pending developer response
I have the same error - only when debugging on device. It show the same error. My device is Dutch ('nl'). Using
instead of the line below doesn't work, it can't find the language files. I do not want a country-specific language. On the contrary, I just need it to format a date, and definitely don't want to include different files depending on the country the device of the user is set to... index.js:
index.xml
Is that your actual code? If so, you're not requiring in moment correctly. You need to do this (not what you showed as line 1 above):
If that doesn't fix your issue, please open a new ticket. That way I can track the work associated with it separately from this issue.
I'm using the syntax as described in the docs: [http://docs.appcelerator.com/titanium/3.0/#!/api/Alloy.builtins.moment]. Mind you: I definitely do not want localization. The problem is that localization is enforced, which means that a Dutch device has to include a (non-existent) /lang/nl file, and an Italian device a /lang/it file. Moreover, even if I want to go this way the /alloy/moment/lang/nl and other country versions gives an error (file doesn't exist). So, I do not want localization, I just want to use the standard English 'en' language so that I can convert the date format on every device set to every country... I don't want to make an /lang/** file for every country my app can be downloaded, just to get the date in the correct format. The problem seems to lie in the following part of the moment.js code in line #963, which makes localization a requirement instead of an option.
Is there any way to circumvent this part?
Can the include requirement please be added to the documentation (maybe here: http://docs.appcelerator.com/titanium/3.0/#!/api/Alloy.builtins.moment) ?
This is not resolved, and it is a very dangerous bug, because on devices with lang !== 'en', *it crashes immediately*! This is the crash report:
The problem is obviously here: function getLangDefinition(key) { var i = 0, j, lang, next, split, get = function (k) { if (!languages[k] && hasModule) { try { loadLang(k, require('alloy/moment/lang/' + k)); // The require fails } catch (e) { return moment.fn._lang; } } return languages[k]; };
moment.lang(Ti.Locale.getCurrentLanguage()); ```
This is not fixed and the solution above does not work in the cause where you want to support ALL languages without creating a i18n string file or load each language manually for moment. Since only an explicitly string can be used to load a moment language it is not possible to load a default. The language of the device is not know before compile time. Please re-open this ticket
I've seen this with 5.2.2 SDK and when debugging: Thread [kroll$1] (Suspended (exception at line 134 in moment.js)) loadLocale(name) [moment.js:134] locale_locales__getLocale(key) [moment.js:163] locale_locales__getSetGlobalLocale(key, values) [moment.js:142] Controller() [index.js:800] createController(name, args) [alloy.js:232] showCustomDialog(args) [dialogUtils.js:114] showAssociateProfile() [associatePopover.js:63] Caused by this call: moment.locale(Ti.Locale.currentLocale);
Closing as invalid. If this is incorrect, please reopen.