I have created a service in angularJS that uses btford.socket-io module to interact with the server.
Since in the service I have implemented some API that I use inside angular at the moment, but for later extension of the application I also need to give access to these API outside angular scope.
So that in future one could just call the function without having the need to create controller and other stuff.
At the moment I did this for a controller
var myController = angular.element($('body')).scope().myController;
by saving the whole controller inside a scope variable.
I was wondering if it would be possible to do the same with a service.
How about:
angular.element(document.body).injector().get('MyService');
Typically not good practice. But sometimes its needed.
Note: document.body is the element Your angular application is mounted to
Another thing you might consider is 'closing' external api with angular via a factory.
eg. return your global or namespaced class or api from an angular factory.
This is essentially what angular does for you. But instead of creating the reference inside angular first and having to extract it, you'd create it outside, and register it with DI as a factory or value.
Related
I'm looking for a way to implement a component level service whose scope is limited to the component and not to the full application, so that for every instance of this component I'll have a separate instance of this service.
Tried creating a service and instantiated it using new keyword(not registered in angular module) in the controller but then I have to provide all the dependencies manually or have to use $injector to get the dependencies in this service class.
Also to make this approach testable I need to expose this property so that one can mock it.
Would like to know more cleaner approach to achieve this where I can inject it in the controller.
I know this is possible in Angular...but I have to achieve it in AngularJs.
Create an angular .factory instead of a .service, inject as normal and instantiate with a new factory() in component. You should be able to find many examples of creating an angular factory with prototypes and returning the factory function back.
I am new to angularjs. I have designed an angularJS service, which is as per the diagram given below :-
Global Service is used as a mean for inter-controller communication. That's, it contains data shared between parent and child controller. Grand Parent controller opens a popup dialog which has parentController2, which in turn open another popup, which has childController3.
Now, What I want is, data stored in global service must be set to null, when its associated controller is destroyed. It's because services are singleton in angularjs, as per my knowledge. So, I don't want service to hold variable throughout the life-cycle of application, even if they are not required.
Moreover, I am using controllerAs syntax and don't want to use $scope(I know that I can do garbage collection in '$destroy' event on scope), to make my stuff compatible with angularjs 2.0.
Is there any way, I can garbage collect variable in service, which are not required, from controller, when controllerAs syntax is used ?
Apologizing for newbie question. Thanks in advance.
using ng-view is one more solution over here for garbage collection as it destroy's the scope as soon as view is changed. It will be used with ngroute but still provides better mechanism for garbage collection.
You can check the ng-view code
function destroyLastScope() {
if (lastScope) {
lastScope.$destroy();
lastScope = null;
}
}
This function is called inside the directive that destroys the scope of the previous scope i.e if you go from parent to child the parent scope will be destroyed
I am trying to call a directive from a service. I have implemented everything but my service scope is coming up empty. Normaly my functions are calling a directive from a controller. But these functions are now needed across multiple controllers so I want to put them in a service. Problem is my service cant see the functions in the directive even after doing dependency injection of the directive into the service.
export interface MyServiceScope extends IScope, directives.MyPanelScope, directives.MyPanelMenuScope {
// a bunch of properties that are not visible in the service scope, only the controller
}
// constructor here, controller does not initialize directives here just in interface and it works fine.
public serviceFunc() {
this.scope.panel.directiveFunc({ // directiveFunc undefined in service, but not in controller
template: "some/html/template",
data: {
item: data
}
});
}
So what do I do about getting the service to see the directive and call its functions?
You cannot inject a directive into a service n Angular. Actually you cannot inject a directive anywhere.
Directives are supposed to be a set of functions that strictly relate to specific DOM elements, and it is usually bad practice to use them to share code between different parts of the app. That purpose can be fulfilled by services.
If you find yourself in the situation where a service needs to call some function from a directive, I suggest that you review your code structure. I don't know the specifics of your case, but you could take the "shared" logic out of your directive into a service, inject that service into the directive and call it from there. In this way the logic called by the directive will be available to be injected to other parts of the application as well.
In Angular JS we declare services and factories. We create a service by declaring a function. We do not call the function ourselves.
Does this mean that is declarative programming. I suppose, the framework does the imperative work?
What is the imperative work being done in the background?
Yes, Angular does most of the imperative work (in your terms) that is related to lifecycle of instances. Here are some things that Angular do for you:
Each service, factory and provider in Angular that is declared by developer, provides angular with constructor function of that service, instance created by factory or constructor function that returns object having $get() method that returns an instance of provider. More about this see here.
All services in Angular are singletons that are instantiated only once (when first time injected to some controller, service, directive or whatever). That means that it is possible to share state using same service injected to different controllers as example.
Besides of it for each service/factory Angular creates provider with the same name as service/factory appended with word "Provider" behind the scenes.
Controllers, directives and filters are very similar to services, but need some special treatment (because of scope/input to be injected). For them Angular also creates a lot of useful staff.
If to say the truth, for about half a year working with Angular every day and night, I noticed that stopped to use new at all, just because there is no need any longer - Angular cares about creating and destroying instances.
We are in the process of migrating our webapp to Angular.js. Traditionally, we created a global object named app and used it to store functions, variables, etc. that were used globally. For example, the active user's name and avatar might be stored in app.user.
With the transition to angular, app is no longer just an object, it is an angular app module. What is the correct way to store data globally like this in an Angular mindset? It could be completely different, that's fine. I just want to make sure we do it correctly.
I would do something as simple as app.global = {}; and use app.global around the site, but if the angular API ever changes to use a property named global, it would be a nightmare to fix.
Angular is fairly allergic to global variables. I would recommend using a service (e.g. UserDataService) to hold this data and injecting it where it is needed (like in a controller).
Your service will be a singleton that can be accessed wherever it is injected.
The correct way to do this would be to provide the value or function to angular's dependency injector via Module.value or Module.constant. See: http://docs.angularjs.org/api/angular.Module
Well, you can also set it in rootScope as:
var app = angular.module('appName'){
//other codes removed
});
app.run(function ($rootScope) {
$rootScope.globalVariable = 'hello'; //global variable
});
Now you can access the globalVariable