2

This is a follow up to How to inherit from base provider (not the provider factory)?. The proposed solution suggests a combination of angular.extend and angular.copy (which can be done with just angular.merge on Angular 1.4) to copy the base provider implementation into all other providers.

But this led to another issue that I was not expecting. With this technique, my providers are now configurable through the provider.setX function, along with direct access to provider.config.x property.

Here's an example demonstrating the issue:

Community
  • 1
  • 1
rfgamaral
  • 16,546
  • 57
  • 163
  • 275

1 Answers1

1

Not really sure what you're after, but this.config.x isn't a variable but a property, and that's why it's accessible.

If you want it to be inaccessible, you need to declare it as a local variable var config = {} inside the scope of the controller/service/factory/wherever you're setting it. Because local variables inside a function/method are inaccessible outside their scope, unless they're closures.

Here's a version of your code that instantiates a function BaseClient (no longer a provider though, just a regular function) which contains a local variable that can not be touched. Again, I don't know if this is what you're after since I don't know which problem you're trying to solve.

http://codepen.io/anon/pen/ZGazqo?editors=101

Jan
  • 5,688
  • 3
  • 27
  • 44
  • Variable or property, doesn't matter, it's just a name and mistyped it. I can't declare it as a local variable cause that will make the "provider pseudo inheritance" no longer working. Unless you have another solution for that :) – rfgamaral Jun 21 '15 at 23:45
  • It matters a lot. variables: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var properties: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors Variables can be inaccessible outside the scope of the object/function, properties cannot. – Jan Jun 21 '15 at 23:57
  • Ok... But can we move past that technicality and try to find a solution for the real problem? – rfgamaral Jun 22 '15 at 12:22
  • I think it's a bit difficult without understanding the problem you need to solve. If the config should be inherited and instantiated for each member and can be changed by each member, why is it a big deal if the `config` property is available? Don't you trust them? Or do you need to take `x` action when property `y` is changed? Wouldn't a watcher be more suited then, checking the property for changes, rather than having getters and setters? I mean, there might be a way to perform what you're after, but that might not be what you really need. – Jan Jun 22 '15 at 17:51
  • What I'm trying to do is explained on this post and on the previous (linked) one, I don't know how to better explain it. This has nothing to do with watchers. Nothing will need to react to some change because nothing will change, this is a provider with a configuration. That's what they are for. I'm just trying to have a base implementation that I can use across multiple providers which share the same implementation (DRY principle). This is all explained in the other question. – rfgamaral Jun 22 '15 at 18:18
  • If the `config` property is available, people might want to change it's properties directly and that can lead to unexpected problems because these are not simple setters. They will throw errors if the parameters are not valid, for instance. – rfgamaral Jun 22 '15 at 18:20
  • That sounds like a watcher problem to me though (watching the variable and validating on change). I provided a version of your script which can have local variables now. Providers can't have instantiated local variables as far as I can tell, so instead my example instantiates a base function. What I mean that you haven't stated a problem is you're not saying "I want to achieve `x` because of `y`", what you're saying is "I want to do `x`, how can I do `x`". And `x` might not be what you need, just what you think you need. Know what I mean? – Jan Jun 22 '15 at 18:26
  • How can this be a watcher problem if **there's no change**? This is a provider configuration problem. I really don't know how to better explain this. I'm not sure I understand what you mean :( As for your new solution, it doesn't work for me exactly as-is, but it might do what I'm looking for with a couple of tweaks. I just got home from work so I'm not going to look into this right now, maybe later before I go to bed or maybe just tomorrow. I'll report back. I the mean time, please read the other question, if you don't mind, and see if that makes the problem more clear for you. Thanks :) – rfgamaral Jun 22 '15 at 18:36
  • Your solution "didn't work" _for me_ because of the base function, I needed it to be something _injectable_. Here's an implementation I derived from your solution: http://codepen.io/anon/pen/aOVzVW - The only problem I can think of with this approach is that you won't be able to inject any services/factories in the `$get` function, otherwise the `$injector.instantiate` will not work (it might not be an issue for me, not sure yet). Do you see any other problem with this method? – rfgamaral Jun 22 '15 at 22:43
  • 1
    You could just wrap the `$get` if you want to inject something or other. http://codepen.io/anon/pen/EjbaGw?editors=101 – Jan Jun 22 '15 at 23:54
  • It's a solution, but will need to be injected on each client, and the instantiate method will need to be adapted for each. This is not a problem when you have a couple of these providers. It will be one when you have 10 or more. It will make it harder to maintain. But works, nevertheless :) – rfgamaral Jun 23 '15 at 08:26
  • 1
    It depends, there are multiple ways you could inject stuff into it, it doesn't need to be done by the client (though as I understood it that was what you were after) http://codepen.io/anon/pen/VLrdEJ?editors=101 – Jan Jun 24 '15 at 20:12