AngularJs directive-service-controller data circulation - angularjs

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.

Related

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.

Routing with Component-based Directives in Angular 1.3?

I have a question about the best way to structure the flow of an app using Angular 1.3. I'm trying to incorporate the 'Component-based Directive' approach as per guys like Matias Niemela (https://www.airpair.com/angularjs/workshops/component-based-directives-angularjs). He says in a video to still use controllers for routing rather than going completely controller-free, but to use directives to create reusable components that have all their dependencies injected.
I'm a bit new to Angular but have used Java mvc frameworks before where a controller written in Java first finishes getting the data needed on the page to be displayed, before some html is constructed and served up. I'm wondering if I'm coming a bit unstuck due to the asynchronous nature of the javascript calls used in Angular, maybe assuming things happen in an order they can't be guaranteed to....
I want to try to make the directives involved have anything they rely on injected (likely via attr's) for increased test-ability etc.
I had envisaged something like the following, for a simple customer listing, with clicking on a single customer in that list going through to a customer details page:
1) a route is defined with a target html page and a controller.
2) The controller gets the list of customers (ideally via a service), which is then available to the html page via Controller As (so Controller MyController As myCont, means the list should be available via something like myCont.myCustomers
3) A Directive is defined to display a customer row's details (name/address, plus a clickable link that passes the customer number as a parameter to a details page)
4) The html page has an ng-repeat to display all of myCustomer in myCustomers, using the Directive. So, I would want to pass the single customer details into the directive via Attr's (for my dependency injection) and then get them displayed for each customer...
(Alternatively, of course, the directive could take in all the customers and display all of them)
So, my question is really whether this is the correct approach to take, or am I missing something about the way these apps need to flow? I've tried unsuccessfully to get it working (posting this from home and my attempt is at work... I'll post the attempt if ppl think it valuable, but really my first question is about whether my overall approach is inherently flawed or not)
And then, secondly, to get the data for each customer passed to the directive, I'm assuming I need to pass the fields in in the html page that has the directive in it, passing something like {{ myCustomer }}... is this correct? (can I assume the Controller will have finished getting all the data before the ng-Repeat tries to cycle through all my customers and send their data to the directive, or not, in which case should I be passing the data via some other mechanism?)
I can't seem to find any examples on the web that tie together Component based Directives, with routing via a Controller, passing data from that controller to the directive, so any help is greatly appreciated!
Thanks!!

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

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?

Best practice to pass data from a controller to another non child or parent controller?

I'm fairly new to angular, after using a video tutorial and reading some documentation, I decided to rebuild an old app of mine as an example with angularjs.
So this app has a table showing some data. It has a form underneath which helps you modify the data from the list. You have a button on each line which allows you to edit the line, it then fill all the fields in the form and you can then save or cancel your changes.
I made a controller to handle the list, it works fine, it gets a json from http.
I used ng-click on my edit button to trigger a function in this controller, giving it the whole object it's supposed to edit.
I made a controller to handle the form in which the edit should take place and I don't really found a 'non-hacky' way to pass the data from the list controller to the form controller.
So, my question is : what is the best practice and/or the common way to get this data from my list controller to my form controler ?
It depends how you are using the form controller. If it's being used within a template using ng-controller attribute, then this controller has access to parent scope, so you can work with list controller's data. (although note some scope-inheritance quirks solved by "dot notation", explained nicely by egghead.io: https://egghead.io/lessons/angularjs-the-dot)
If you're launching your edit form in a another url (e.g. /items/2/edit) and handle it in a routing configuration, then you can use resolve property to pass any data to the controller: $routeProvider docs.
You can pass the entire object as parameter
<row ng-repeat="theModelInRow in modelList" ng-click="edit(theModelInRow)">
if form controller isn't a nested controller of list controller on view, then you can use rootScope.

Resources