Angular.js Directive on condition...rather than hard code in html - angularjs

Using Angular.js.... not sure how to implement this....
I have a seperate service and directive that calls out to a api and if that api returns a json that has the word success in it, then run a separate directive that returns a function that creates and modifies elements.
The problem is that the separate directive would have to be hard coded into the html...such as <directive blah blah></directive>. I can't hard code it because...it is conditional... the service api call may not return success.
Since element creation and modification has to go into directives for conventions(and possibly even scope...not sure if I will modify that yet or not)...and this is dynamic/conditional....can I call the directive as a function in a controller or service? Rather than hard code it into the html? If not, what other way could I do this?

Related

AngularJs directive-service-controller data circulation

I just couldn't wrap around my head which way is the correct one and couldn't find a straight forward answer sooo... :) I have the data being pulled from a server api and that data is used inside a directive. Problem is that with promises I have to setup watches inside directives otherwise I get undefined data... Why should I pass it from the controller and not just use the service inside the directive itself? But then the controllers would be left empty. So if they are meant to bind data what does that exactly mean? I mean all the data could just be pull straight inside directives and they would handle everything, like components.

passing and manipulating data between a controller, directives, and a service --angularJS

My angular skills are not great and I have encountered a problem which has stalled my progress.
Initially I had a Main controller and 5 directives. The directives and the main controller were happily working together, by passing data to/from the main controller through scope. Until the 5th directive required the data from all the other directives to be computed. I tried passing the data from all the directives to the main controller and then passed it to the 5th directive. but unfortunately due to the asynchronous nature of both data and js it did not work i.e. it is not being updated in some parts of the code and i kept getting null. I tried putting a $watch even that did not work.
Upon recommendation of a colleague, I introduced a service to transfer data between the directives and controllers. So no I have a Main controller, few directives and a service.
The service loads data from the DB for each directive through multiple queries. and Each directive performs computations on their set of data. but still the same problem of data not being available / undefined at different points in code exists. I don't know what else to do. If anyone can suggest a solution that will be a massive help.
Thanks in Advance

Is it bad practice for an angular directive to request data

Consider for example a currentUser directive.
I could let the controller use a service to get the data about the current user, provider it to the directive and let the directive render some "hello {user.name}" template.
Alternatively I could have the directive have a dependency on some currentUserService and in the directive's controller ask for currentUserService.getCurrentUser.
Is one of the two significantly better then the other for any reason?
I tend to go with the first option but not sure if the using the second one would not have a benefit of having all the current-user-logic less spread around...
Thanks
As long as you're requesting the data from a service, I believe having a dependency toward it in a directive is fine.
The main aspect of the controller is having access to $scope, not much more.
There are two scenarios and it really depends on the purpose of your directive:
the directive is only used to display user-data (in a complex way)
the directive displays data and manipulates it (according to user-input)
SCENARIO 1
Since the only purpose of the directive it to render the data somehow, the directive should not be responsible for retrieving the data.
So you decouple the logic how to access the data and how to display the data. This way you can also use the directive for users other than the currently logged in user.
If there should be some special things visible, if the user is logged in, the directive should use ng-if or ng-show for that (and maybe a parameter to disable that view-part).
SCENARIO 2
In this case the purpose of the directive is to provide a gui for some business-logic (service functionality). Therefore the service should be injected into the directive.
Remark:
PERFORMACE
If you get the data via method-call from your service, this method will only be called once in every digest-cycle if you load the data and inject it into the directive-controller. Otherwise it may be called once for each occurance of the directive.
INTEGRITY
Remember, that if your service-method requests data via http and you are using the directive for example 3 times in a view and the directive calls the service-method itself, this will result in 3 identical requests which may have non-identical results (i.e. someone other changes the data while the requests are processed).
It is always better to use service to reside business logic.You should use service to get data and inject that service to directive.Do not use controller to communicate between directive.Service is meant for that purpose, initiate once.

Call a normal JS function of other file after data from $http is loaded and is binded to the views

I want to call a regular JavaScript function after my webservice call has completed and all the data is binded to the respective views.
This JS function is in another file so I cannot access it in my Controller using $broadcast etc.
My webservice call gets data and fills it in an accordion, but the problem is the webservice is sometimes taking too long to return data; due to which the normal JS function is called prior to the completion of webservice call, the purpose of the normal JS function here is to provide expand functionality to the accordion li's which are filled from the webservice call, due to the above reason, the expand functionality is not binded to the li elements as they are generated after successful data return.
I do not want to use $delay or anything of that sort as I cannot say for sure how long it will take for the data to return.
What is the way to get around this, where and how can I call my normal JS function?
Can I defer the call of function in the directive itself or somewhere in the HTML file?
Wrap your 'normal JS function' using AngularJS 'service' / 'factory' / 'provider', you can then access it from anywhere using dependency injection of AngularJS.

How to output data from a directive to a controller, and should I?

Use case
For use in a form, I created a directive that tracks changes in an array. It allows changes to be reverted and deletions and additions to be stored separately. It allows for an array (one to many mapping in the database) to be updated incrementally (rather than requiring the server to either diff, or rewrite the entire list).
Problem?
My question is about the way I expose the functionality to the controller's scope. I currently use an two-way databound attribute on the directive's scope. This works, and it seems reliable (of course you can easily break it by reassigning the scope's value, but intentionally you can break anything).
Code
You can see this plunk to see this in action. It allows methods on the directive's controller to be called from the view and the view's controller. (I am using the directive controller intentionally because that's what I do in my actual code for the directive to directive communication, but this could also just be placed in the linking function.)
Question
Is this way of doing it bad design? Am I completely throwing AngularJS out of the window now and hacking in my own code. Are there any better ways to expose functions from a directive (keep in mind that there'll be multiple of these in a single form).
It's very easy to pass in my-attribute="someFunction()" to have the directive be a consumer of the view controller. I can't find a better way to do the opposite and have the view controller consume from the directive.
Alternative?
I've been thinking about using a service here, in which the service will provide an object that is instanciated in the view, passed to the directive, and have the directive blurp out it's results to that object. Then in turn have the view controller consume the information from that service's object. Would this be a better approach?
There's nothing wrong with your approach. In fact built-in angular directives such as ng-form use this approach to store the controller in the scope (see the name property of ng-form) http://docs.angularjs.org/api/ng.directive:ngForm
For more re-usability though I would put the api methods on the controller and then put the controller itself in the api:
this.getChanges = function () {};
this.resetChanges = function(){};
$scope.api = this;
In directives, the main purpose of the controller is to serve as an api for other directives (if you didn't need an api for other directives you could just do everything in the link function). Doing it this way ensures the api is available both on the scope as well as to any directive that 'requires' the oneToMany directive.

Resources