AngularJS transfer data between one component to another - javascript

Have some data for one controller JSON, I fill by this data in ng-repeat my view.
But when selecting this data from view I need pass selected data to Form Controller fill all forms.
I don't know how to do this in angularJS with components. I built service, which parse data when i select it and pass to Form Controller. But it's additional work parse it again by service.Maybe exist some more good way how pickup just id, and Form Controller load it automatically when get id's from service.
AngularJS really hard for all ways as I understood :(

It's better to provide some code samples with the question. Actually you have 3 main ways to share data between modules - parent controller, rootScope and services. Ok, there is event emitter here, but I heard opinions that it's not 'Angular way' to use events, because it's hard to maintain this architecture later. As I understood, you are using service for this porpoise and it's fine. Since Service is Singleton in Angular you can use it not only to share reusable peaces of code but and for sharing data between controllers.

Related

Initialize the server data from ng-init directive via calling angular controller function?

We have developed one Enterprise application, The complete client side framework is built on AngularJS and the server side framework is on ASP.NET Web API. In the application we have 350+ html pages and 250+ Web APIs. There are lots of areas where we initialize the server data from ng-init directive via calling controller function. Because in our application all data is coming from the ASP.NET Web APIs. But I was surpised upon the documentation for ng-init, which says, in a nice bold outline :
The only appropriate use of ngInit for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
I would like to get feedback from Industry Experts/ Angularjs Core Team Members on my concerns.
Let me brief first what we are doing in the application, for showing a industries list we load the industry HTML page and show the server data. The HTML template code is shown below:
<div ng-init="initIndustries()">....</div>
The "initIndustries" function will be called from initialized industryCtrl. industryCtrl.js code is shown below :
app.controller("industryCtrl",["$scope",function($scope){
//Sets the server data in the $scope property.
$scope.initIndustries = function(){
//perform ajax request and set the data into the $scope property.
}
$scope.initAddIndustry = function(){
// perform ajax request for getting a dropdown data on Add Industry Page.
}
}])
I have few concerns based on Angularjs Doc and Anglarjs-styleguide guideline on Keep Controller Focused which is mentioned below :
Are we doing something wrong to initialize the data via function because all data is coming from the Server APIs?
Current initialization approach is against the industry practices in AngularJS based application. if yes, then which approach we need to follow in the application?
Do we need to create sperate controller for every view just for the shake of client side test coverage, as per the angularjs-styleguide?
The reason to implement the above approach(initialize the data from ng-init directive via controller function), Due to large application my initial thought was to follow MVC philosophy of decoupling the code and separation of concerns.
Angular is known to be Model-View-Whatever. So, it totally depends on you whether you follow a structure in the angular application or not.
Not following a structure has some pros and cons.
Pros
1. A data that is available in one controller can be shared across many views so you won't have to use $rootScope or HTML5 localStorage/sessionStorage to pass data from one controller to another.
Cons
1. As data in controllers is available in multiple views so it is very difficult to maintain the data because the data is obviously bound to views and there will be many implicit angular watches on the same data. That will give bad performance.
Now answering your point 1 and 2 of using ng-init to intialize data in controller. I don't think that will be a good approach because you have made the initialization dependent on the view.
Lets take a scenario in which your view is not found on request and then the initialization won't occur. And as initialization won't occur, there will be garbage values / bugs in controller. So its better to separate the controller initialization from view.
Answer to point 3 is that when you are using a separate controller for every view, you are actually avoiding monolithic code approach and that is always a good point because that leads to modular approach. Separation of concerns in Angular JS is not just done using separate controller for every view but services and directives are also for this purpose in the long run.
Hope that helps you in some way.

Using a service for small task

i been reading about services or factories in angularjs, but im having some trouble finding the best solution, basically i need to pass some data from one controller to another controller, it is a boolean value, but i dont want to create a service for just a small task.
I believe that wouldnt make much sense for just a small job. is there other way in angularjs for this type of situations? Where i could pass small data between controllers. I been looking around in angularjs documentation, but cant figure out the best solution.
Use $rootScope.emit()
in Controller A
$rootScope.emit('toggle',true);
in Controller B
$rootScope.on('toggle', function(value){
})
For tiny items, you could use parameters. The the end user, they'd look like a part of the URL string. This is avaible with and without using ngRoute. Have a look at this stack question.
For more complex data or data that's unsuitable to displaying to an end user, use a service or factory. Seems like overkill, but it gives you greater flexibility.
A $broadcast/$on pattern just gets messy and harder to troubleshoot.
If it's parent/children controller, you can transfer your value with $scope or $emit/$broadcast.
If controllers are on the same level(siblings) you can make wrapper controller for them to store shared data.
If you think there would be similar requirements for other tasks you can consider service, and making it abstract and reusable(some sort of helper).
In any way, you didn't provide enough of info, and there could be a lot of solutions until we see real example.
If your controllers have a child parent relationship (in any level) then you can try with $broadcast or $emmit to throw the data and $on to catch that with a a event. Otherwise inject $rootScope to one of them and trigger either $broadCast on the monitor of $rootScope, or $emmit on the monitor of $scope and catch thet data using $on('eventName', function(ev, data){}) correspondingly.

Angular: How to go about refreshing service data

I am fairly new to Angular and trying to build an Angular application.
I have a lot of data that needs to be used by multiple controllers throughout the app. As I understand it, that is the perfect situation to use a service.
I am planning on storing this kind of data in services. For example I plan on having a users service which all controllers that need user data will inject.
I would like the users service to hold the master list of users and any controller that needs users to just use the one instance of service list.
I am having trouble envisioning the pattern though. I mean:
1) What is the standard way of having the service refresh its data from the server? I realize that I could just go and request the entire list of users every 10 seconds from the server but that seems kind of heavy weight...
2) Ideally I would like to be passing around only a single instance of each user. This way if it gets updated in the service, it is sure to be updated in all of the controllers. I guess the other option is to have the service broadcast an event every time it updates a user? or to use watchers?
3) What is the pattern by which the controllers interact with the service and filters? Do the controllers just request data from the service and filter it in the controller? The other option is to have the service do the filtering. If so how do I communicate the kind of filtering I need done to the service?
I think that by using some kind of solid pattern I can take care of alot of these issues (and more that I am sure will arise). Just looking for advice on some common patterns people employ when using singleton services.
Thanks in advance.
Answer to point 1. A service is just a singleton. How you store and refresh data into it has nothing to do with its nature. Not sure why you want all user data inside a service (unless you are building a user management app), but you could use several techniques like polling (eg. using $timeout ask for new users and append them to the existing ones) or push (eg. socket.io/signalR which will push you the payload of new users when available). This can be done both inside the service itself or by a controller that will add/remove data to the service (eg. a refresh users button in the UI)
Answer to point 2. You can bind/use the reference of the data inside the service directly into your controllers using a getter so that changes to the data are shown instantly (given that are two way binded, if not use events).
Answer to point 3. You can apply filters inside the controllers or in the view it self (not recommended). You can also have a function in the service where you pass the filter or filter params and get the filtered copy of the users collection back (since you will be using the users collection directly in many controllers at once you shouldn't modify that, unless that's desired). If you are reusing the same filters again and again across the controllers you can have a function for each filter that returns the filtered collection with a "hardcoded" filter. You can even have helper function in the service to help you assemble complex filters or have multiple copies of the collection already filtered cached(if you find you are using the same filter again and again)

Angular.js: templates and handling data between views

I'm trying to grasp the main principles related to the next issues:
Templates
Data Handling
$resource vs $http
As i see it i'd like to implement few views in my app which share few html templates and also share some data. for simplifying my issue i'll describe a scenario which is almost equivalent.
as u can see there are 2 views (though there will be more!) who use 3 html markups while one of them is shared in both views (GeneralInfo). Also, both views share data which will be normally created while using one of the view's controller.
What principle of angular should be used to make sure that while changing the route i could keep my data shared between the views.
Should i use app.value('myVal', ..) which is Global variable?
Should i pass it like a service to all of my controllers?
More technically, how should i implement same html in both views? could u example that?
How should a view with it's markup contain 2 templates and how and when it is rendered?
what's the difference between $resource and $http and when each shouold be used?
1) should use a Service to share data between controllers. technically, you could attach values on $rootScope and it would be visible across controllers, but that is considered bad form and can cause problems later (like using global variables -- can definitely have unintended side effects as the project grows if someone accidentally attaches a conflicting value).
2) not sure exactly what you're asking here. you can load a partial based on the given route/state (using ngRoute or ui-router). two different routes could use the same generalInfo.html partial, but with different data being pulled in their respective controllers. is that what you're asking?
3) $resource is an abstraction of $http -- if you're pulling data from a REST server, $resource may be a better fit, as it abstracts a little of the wiring necessary. however, if the server varies from traditional REST principles too much, or if it's not REST at all, you may just want to roll your own data access directly with $http. Of course, if it's REST and more complex, also consider restangular -- which is a more feature rich abstraction.

Best practice for node - mongo - angular

I have an app I am designing using node/mongo/angular, what I am not getting is how is the best way to get my data from mongo into my pages? I can use node, and thru my routes send back data from mongo with my template(hogan in this case), and bind using mustachejs. That works fine for most things. I have one screen that has a decent amount of drop down lists, to bind them for an edit scenario now seems a challenge. I would like to get them bound to an angular model and go about it that way. Is it better to get the data thru the route in node, then use something like ng-init and get it into angular? Or would I be better off not getting the data thru the route in node, and then using angular to perform a "get" request and bind that way?
From the documentation of ng-init, more precisely from the red warning alert at the top of the page...:
The only appropriate use of ngInit is for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
So no, do not use ng-init. While that can be a good strategy for lazy migrations from regular applications to single page applications, it's a bad idea from an architectural point of view.
Most importantly, you lose two things:
An API. The benefit of SPAs is that you have an API and that you're constantly developing and maintaining it, even before it has external users
A clean separation of concerns. Views are strictly limited to presentation, can be cached by the client and all data is transferred through JSON API endpoints.
I would say that the best way to get data from Mongo into your page, is as mnemosyn said, using an API.
Basicly, you can have your API route, f.ex '/api/data' configured and then it can be used by a angular service, (which can use ngResource to make things easier). Any controller that wishes to access this data can use the angular service to get it, do some stuff with it, and then update it using the same angular service.

Categories