ngUpgraders / ng-forward

The default solution for those that want to write Angular 2.x style code in Angular 1.x
411 stars 36 forks source link

Method for getting a providers registered service name #47

Closed david-gang closed 8 years ago

david-gang commented 8 years ago

There are modules where we need to pass in names of factories to their functions: For example angular translate let you pass

For more information look here: https://github.com/angular-translate/angular-translate/wiki/Error-Handling

Now the problem comes that if i write the syntax in the angular2 style i don't have a name anymore. If we don't have uglification everything goes ok

if we have uglification:

Let's say i have a class called Foo The name of Foo is then changed to e. I lost the name. What can i do?

MikeRyanDev commented 8 years ago

If we exported a function called something like providerName that you could use to get the runtime service name ng-forward generates for you would that be helpful?

You could then do something like:

import {providerName} from 'ng-forward';
import MyService from './my-service';

$translateProvider.useMissingTranslationHandler(providerName(MyService));
david-gang commented 8 years ago

How would this work? Would this give me the original name or the uglified name?

MikeRyanDev commented 8 years ago

Uglified name.

david-gang commented 8 years ago

I can get this also through the name property. I don't have a good feeling about this. This is due to the fact that the name of the angular1 object is his Id and if i don't have control over it i feel that things could go wrong in production, for some reason. In fact i tried to use the .name property and it somehow injected another class :-( These are the bugs that you need last. If the name cannot be preserved, it may be a normal limitation of not using the angular-translate module with ng-forward.

If you think the same then we can close this discussion and add to the readme that there are modules which are not yet ng-forward ready.

MikeRyanDev commented 8 years ago

It injected another service because we create a map at runtime of classes and names. Take this quick example:

// Module A
class A{ }

export default A;

// Module B
class A{ }

export default A;

Thanks to uglification, both classes now have the same .name property, so we knew we couldn't reliably use the .name property in ng-forward. Instead, we generate a name that we think is unique. This keeps ng-forward working correctly when the source code has been uglified.

You can take a look at the code that handles this here: https://github.com/ngUpgraders/ng-forward/blob/master/src/util/decorator-factory.js

My proposed providerName function would call providerWriter.get('name', MyService).

david-gang commented 8 years ago

You saved my day :-)

Another option would be that the @Injectable annotation would get a string which is the name of the object. I know this is less the angular2 way but it makes it easier to debug problems.

timkindberg commented 8 years ago

I think the getProviderName method would suffice. I rename the issue to reflect that this is an enhancement request.