Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

ngPluralize throws "TypeError: undefined is not a function" when including locale file #7774

Closed
eranimo opened this issue Jun 10, 2014 · 11 comments

Comments

@eranimo
Copy link

eranimo commented Jun 10, 2014

I'm on Angular 1.2.6 (but a quick upgrade test did nothing) using a french locale bundle

<script src="bower_components/angular/angular.js"></script>
<script src="https://code.angularjs.org/1.2.6/i18n/angular-locale_fr-fr.js"></script>

Here's a snapshot of my bower file:

   "angular": "1.2.6",
    "json3": "~3.2.6",
    "es5-shim": "~2.1.0",
    "angular-animate": "1.2.13",
    "jquery": "~1.10.2",
    "jquery-ui": "~1.10.4",
    "angular-resource": "1.2.6",
    "angular-cookies": "1.2.6",
    "angular-sanitize": "1.2.6",
    "angular-route": "1.2.6",
    "underscore": "~1.6.0",
    "moment": "~2.5.1",
    "angular-moment": "~0.6.2",
    "angular-strap": "~2.0.2",
    "angular-motion": "~0.3.2",
    "bootstrap-sass-official": "~3.1.1"

And the error in question:

TypeError: undefined is not a function
    at Object.ngPluralizeWatch (http://127.0.0.1:9000/bower_components/angular/angular.js:18850:37)
    at Scope.$digest (http://127.0.0.1:9000/bower_components/angular/angular.js:11753:40)
    at Scope.$apply (http://127.0.0.1:9000/bower_components/angular/angular.js:12012:24)
    at done (http://127.0.0.1:9000/bower_components/angular/angular.js:7818:45)
    at completeRequest (http://127.0.0.1:9000/bower_components/angular/angular.js:7991:7)
    at XMLHttpRequest.xhr.onreadystatechange (http://127.0.0.1:9000/bower_components/angular/angular.js:7947:11) 

The rest of the locale bundle seems to work, but the pluralize directive isn't using it.

@rodyhaddad
Copy link
Contributor

It's hard to find a problem without some code that reproduces it.

Can you provide us a simple plnkr that reproduces the issue?

@eranimo
Copy link
Author

eranimo commented Jun 10, 2014

I'm using ng-pluralize in two locations, both with defined numerical values

<ng-pluralize count="merchantData.locations.length"
    when="{'0': ' Locations',
         'one': ' Location',
         'other': ' Locations'}">
</ng-pluralize>
<ng-pluralize count="inventory" when="{'1': ' offer', 'other': ' offers'}">
</ng-pluralize>

@eranimo eranimo closed this as completed Jun 10, 2014
@rodyhaddad
Copy link
Contributor

You closed the issue. Is it because you found a solution?
Don't hesitate to share it for others that might hit the same problem.

@Sija
Copy link

Sija commented Nov 23, 2014

Happened to me as well with Angular 1.3.3 and polish language bundle.

<script src="bower_components/angular/angular.js"></script>
<script src="https://code.angularjs.org/1.3.3/i18n/angular-locale_pl.js"></script>
  scope.$watch(function ngPluralizeWatch() {
    var value = parseFloat(scope.$eval(numberExp));

    if (!isNaN(value)) {
      //if explicit number rule such as 1, 2, 3... is defined, just use it. Otherwise,
      //check it against pluralization rules in $locale service
      if (!(value in whens)) value = $locale.pluralCat(value - offset);
       return whensExpFns[value](scope);
    } else {
      return '';
    }
  }, function ngPluralizeWatchAction(newVal) {
    element.text(newVal);
  });

return whensExpFns[value](scope); is the offending line, which fails with above error when pluralization function returns the key that doesn't exists in when attribute. IMO angular should check translation key for existence and use other (which should be always defined) in case it'll fail (sth along return (whensExpFns[value] || whensExpFns['other'])(scope);)

@gkalpak
Copy link
Member

gkalpak commented Nov 23, 2014

ngPluralize has been refactored lately (see #10022) and as a side-effect, resovling to a non-existent key, should result in an empty string.
Could you check against the latest snapshot and verify that there is indeed no error thrown ?

@lgalfaso: Do you think it is a good idea to "default" to 'other' when the key is not present in whenExpFns ?

@lgalfaso
Copy link
Contributor

@gkalpak we should not default to 'other' as this is not what other libraries do. To default to the empty string is the right thing

@Sija
Copy link

Sija commented Nov 23, 2014

@lgalfaso Such approach requires explicit definition of all keys, even thought it's not necessary.

Take this for example:

<ng-pluralize count="days" when="{
  'one': '1 dzień', 
  'few': '{} dni',
  'many': '{} dni',
  'other': '{} dni'
}"></ng-pluralize>

Why shouldn't we default to other? It's most generic of all pluralization keys and so it fits at all times. IMO it's certainly better than seeing nothing at random times (i.e. when $locale.pluralCat returns inexistent pluralization key). Omitting one of the keys doesn't mean that the user want to skip this translation but rather it's the same with other.

@lgalfaso
Copy link
Contributor

@Sija

It's most generic of all pluralization keys and so it fits at all times.

That is not true as it depends on the language

@Sija
Copy link

Sija commented Nov 23, 2014

@lgalfaso yes it does, but it is still IMO far better to see incorrect grammatical form with some information in it (lets say "5 godziny" where proper form would be "5 godzin") than empty string which conveys no message... that's my line of thinking at least.

@lgalfaso
Copy link
Contributor

@Sija every other library that I know about that handles plurals do not default to other when a key is missing. This includes android, iOS, the ICU project...

Now, if the problem is to detect these, then I would agree that it would be nice to generate a warning when being asked for rule and it is missing

@Sija
Copy link

Sija commented Nov 24, 2014

@lgalfaso fair enough! +1 for warning in case of missing pluralization keys

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants