Write initialization function for directive in angularjs? - javascript

I am developing one directive for my grid control, and i need to get some common resource data from server before i build the grid control.
How i can write initialization function for the directive? I need it to execute before loading the control to DOM and it has to be something like lazy one(it should execute only when the DOM got directive).
I have written one function in the controller of directive to get the resource from server, but the directive execution is not waiting for the server response. it is just continuing the execution and throwing resource value is undefined.
Please anyone help to me solve this?

Either you could use the resolve function of your state to have the data loaded before the controller is instantiated at all, see https://docs.angularjs.org/api/ngRoute/provider/$routeProvider
Or you could do it the angular way and
initialize an empty array for your data in the controller
make the ajax request in the controller, and update the array when the response comes in
watch the array to update the dom. If you simply use ng-repeat to show the data, that watch will be set up automatically. If you do "manual" DOM manipulation you must use $scope.$watch() yourself.

Related

angular js , ng-model not ready for third party directive

I am using https://github.com/ezraroi/ngJsTree and I have come across the following problem.
My ng-model is a AJAX request and when my controller fires, data is not yet ready, so it does not render anything.
<div ng-controller='myCtrl'>
<div js-tree="treeConfig" ng-model="treeData" should-apply="ignoreModelChanges()" tree="treeInstance" tree-events="ready:readyCB;create_node:createNodeCB"></div>
</div>
https://plnkr.co/edit/IRaqvd0DPcqkxgo0xoqa?p=preview
Depending on the structure of your application, you may have a few alternatives to handle this situation. Create a service that is responsible for reading the data. Then you can do one of the following:
make router to wait till the reading is resolved before
navigating to the view. Here is a related SO question: AngularJS $http.get with resolve
add event listener to the controller and
make service to emit/broadcast event when the data is ready.
In both cases, you may want to read data from service.

How to pass parameter to function in AngularJS with promises

I wan to send parameter to service function.
getQuestions : function(stateCode) : questionResource.js
stateCode is set in $scope from the response of dtoResource.rc1Step1DTO()
angular
.module('autoQuote')
//Do initalization on page load
.run(['$log', '$rootScope', '$state', 'dtoResource', 'questionResource', function($log, $rootScope, $state, dtoResource, questionResource) {
$log.info('Post DTO on page load.');
dtoResource.rc1Step1DTO()
.then(questionResource.getQuestions)
.then(function(questions) {
$rootScope.questions = questions;
console.log('Obtained questions. Assigned to rootscope');
})
.then(function() {
console.log('This should be printed after the above methods are done executing');
console.log($rootScope);
});
}])
How to pass state code to the other function.
its position in scope is
$scope.postAutoQuoteObj.SessionInfo.StateCode
Below is the plunker for code
http://plnkr.co/edit/Op1QDwUBECAosPUC7r3N?p=preview
your module autoQuote.run() will only be called once during your applications loading. So don't expect to have it execute again.
you are close to the right answer. you just need to do some reorganization. One tip I would offer is to worry about creating a directive later, first get the controllers, routes working first.
You have created an excellent framework to start. you are using ui-router.
this means that you can tell ui-router what controller to execute when a state is requested. so the life cycle for your application is as follows
module.run //any code in here first. only on intial load
module.config //in your case app.config which creates your states.
then depending what state you are viewing based on the url;
the controller for that state (or view) will be executed
so if you add another state config for / you can bind that state to your autoQuoteCtrl.
additionally, there are a number of other issues, such as attempting to use ng-model and value in an input element. this is not correct.
you are not implementing your ui-views. this will mean your controllers will never execute. technically, it your case autoQuoteCtrl would be executed but only because you forced it onto the page using ng-controller, which is what ui-router is designed to avoid.
which I think is why you ended up placing your code in .run(). This was the only place you found your applicaton would "run" the code on page load which is false, it was only running because your app loaded. Sorry if I'm being redundant. But it is an important point.
Also, you are trying to access your json data by passing statecode to your resource. that is not how $resource works. you pass the name of the resource, and it will return everything at that resource. then you filter the code after the promise is returned. you only have one resource. that is "CA.json" so therefore you should be able to get away with only one line in your resource service and only need one resource service. You will need additional non-resource services that can do the heaving lifting of filtering out the correct data from the JSON. typically this is why an app would call out to different resources, so that each one returns the model needed, not a single monolithic resource.
and you should never ever ever be using document.getElementById() you are using angular, so you do not interact with the dom directly
finally, here is a much much revised plunkr to help guide you in the right direction.
http://plnkr.co/edit/dUJm01uu7RnhltC2pLLb?p=preview

Angular service using $watch to do $http call when a property is changed

I'm pretty new to Angular and wondering what the best way to handle this is. My app is structured with a service that keeps track of the app state and currently loaded data. I inject this into all my controllers so the app state will be shared with them and can also be changed between controllers by using the service. The service is outlined a bit like this:
app.factory('AppStateService', function() {
return {
selected_section: "blog",
data_of_selected_section: {here_comes_data_from_an_api}
}
}
As said, I inject this in all my controllers and bind them to the controller scope, so they can all change those properties and this works perfectly. However, I'd really like the service to automatically do an $http call to an API, whenever some of the properties change. When the data comes back from the API, I want this data assigned to a property so the controllers can update based on this data.
In the above example for instance, if a controller changes selected_section from e.g. "blog" to "main", I want the service to do the $http call and put the returned data in data_of_selected_section to let it propagate to the controllers. I could of course do this directly from the controller and push the result to the service from there, but then I'd have to replicate that code in each controller. Thus, I'd rather want the service to do it by itself.
What is the best way to do this? I guess I'll have to build in a $watch or $watchCollection somewhere in the service but I have a hard time wrapping my head around exactly how to do so. Especially since I could easily imagine that doing it the wrong way could kill performance.
On a side note, the reason I want to do it this way is because I'm doing data visualization and thus it is mostly my interface and not my data that will change. Thus, I'd really like to store my data and app state "globally" in a service. I don't know if it makes sense. Any help would be greatly appreciated!
You could use .run as this method will instantiate the service on every route change.
app.run(function ($rootScope, AppStateService) {
$rootScope.$on('$routeChangeStart', function () {
$rootScope.data = AppStateService.data_of_selected_section
});
});
You can write your http call inside the service as it will be automatically called whenever there is a change in the route

Detect if page successfully rendered in Grails

I have a grails application where i have to detect if page is rendered successfully.
So, if I have render view: "mypage", I want to know if this page was rendered successfully by tomcat. Whether it reached user or not is not concern here. That is another part which can be tracked by using javascript events.
The solution that comes to my mind is using error controller and url mapping to map any issue like 404 or 500 to one controller but that controller is somewhat generic and will be handling multiple issues and not just this one.
So, Is it possible to exclusively know for this render call if it was rendered properly or not?
Try attaching a filter to the action with the afterView filter type. The documentation mentions that the first argument is an Exception, so if the first argument is null, then the render succeeded. (Also note that the documentation mentions afterView is called before the SiteMesh layout is applied, if that matters for this particular problem)

AngularJS not refreshing view after model changed as result of an event

I've prepared a Plunker with a simplified scenario of an app that I'm coding where this is happening.
A little explanation of the scenario:
There is a controller that loads into the $scope a list of transactions (objects of type Transaction)
This controller listens to an event produced by the service that is responsible for persisting new or updated Transaction objects, and then reloads the model
The view renders the transaction list with ng-repeat
Every transaction can be updated (commited or rolled back) individually
The AngularJS app has a run() block that creates a new Transaction object every 2 seconds, simulating that these transactions come from an external source (an $http request against a server, for example)
What you will see is that no reload of the view is done when the model is reassigned with a fresh list of objects after receiving the event that the service produces.
I've been pulling my hair off the last 48h with this. The most common cause for this kind of behaviour is to modify the model outside AngularJS and not calling $apply(), but (i think that) this is not the case.
Also tried to check $scope.$$phase and the calling manually $apply or $digest (even if this could be considered potentially bad) with no success at all.
Am I doing something wrong? Is this a bug? Is there any other strategy that I could apply?
setInterval is also "outside of Angular" and I'm not sure if you tried using $apply there. If you wrap the transactions.persist(t); in app.js within $rootScope.$apply() you will see the list refreshing every two seconds. Changes produced by "COMMIT" and "ROLL BACK" buttons are also being displayed immediately.
Working plnkr

Categories

Resources