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

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

Related

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

Meteor: Subscribe for getting more datas doesn't work

I'm having a problem with Meteor, I have two subscribes : one is used in the main page, while the second one is called on a specific page. The 1st returns some datas about all the users, and the second returns all the datas from one specific user, but my problem is that this subscribe doesn't work on the first loading of the page.
I think that, to the extent that I already have datas from that particular user, the subscribe is not used; if I refresh the page, I have all the correct datas...
I really don't know what to do, thanks for your attention!
It is hard to figure out where the problem is without any code. Make sure your subscriptions are being run whenever that page is visited or that template is created. This means putting the sub either at the router level in the waitOn or subscriptions functions, or putting the sub at the template level within its onCreated callback: Template.myTemp.onCreated = function() { this.subscribe('myPub'); }

How can I redraw the ITHit Ajax File Browser in an Angular SPA when I've got all the instantiated parts?

For various reasons I will not go into, I have successfully wrapped the ITHit Ajax File browser inside of an Angular Controller, which itself is loaded and wrapped in an Angular-UI-Router UI-View.
All of the settings are configured through preceding service calls (to support a cloud environment with shifty urls), and I've even gotten through all of my CORS (Cross Origin Request) issues, and we've wired in a custom Oath2 implementation on the DAV server. All of this is successfully working with the ITHit File Browser as a pretty centerpiece for our content-browsing implementation.
As of now, when I navigate certain areas, the Angular-ui-router tweaks the Url, the view responds, and the Angular Controller wrapping ITHit responds to the view change, and (without reloading the view) re-fetches the appropriate DAV url with available IT Hit commands ( e.g. SetSelectedFolderAsync )
Here's my (hopefully simple) challenge: when I navigate to certain areas - Angular-UI-router simply reloads the containing UI-View with new content, but when I return - the ITHit Ajax File Browser does not redraw.
Here are some guidelines to my challenge (ignore-able if you offer something I can work with):
I'd prefer to avoid having to "hide" the ITHit container (because
it's irrelevant and I don't want to have to manage keeping it up to
date as state changes in the view. These changes affect DAV paths). Also I don't want to worry about unnecessary network traffic.
I'd really like to let Angular-UI-Router do its thing with the
ui-view in which the browser is resting.
I'd like to keep
whatever calls need to be made invokable to the Angular Controller
(it's managing authentication, path resolution, and contextual
settings config - which change as users navigate).
Everything (well most important things) generated by the ITHit solution is
stored in a Singleton ('DavBrowserService') - so when I return to
the file-browser view, I have everything stored from the initial
instantiation including:
an instance of ITHit Object
the produced instance of the ITHit.Loader
an instance of the previously produced AjaxFileBrowser.Controller Object (ITHit.oNS.Controller)
an instance of the previously produced WebDavSession Object ( ITHit.oNS.WebDavSession)
With the above in place - I'm hoping that I can simply re-wire these instances back on to the now-returned dom-node ('afb-content-div').
Any help is MUCH appreciated!
UPDATE: The below "answer" while appearing to be functional - indeed was NOT. However, I have worked around this issue by grabbing the DOM instance and storing it memory when the user navigates away, and re-attaching it after the user has navigated back to the appropriate area. This way all of the ITHit Magic is still tied to the right DOM node, and I don't have to worry about the partial re-instantiation weirdness. Seems to be pretty solid now.
I figured it out!!! It looks like if I re-instantiate the controller by calling:
var controllerInstance = new ITHit.oNS.Controller( originalSettingsObj );
Everything rewires magically! I've wrapped the above code with some detection for whether the 'afb-content-div' HTML DOM node has children.
After much digging in the code, it looks like this is the argument object returned to as a parameter to ITHitLoader.oninit callback (From the AjaxFileBrowserLoader instance).
Thanks for playing!

Write initialization function for directive in angularjs?

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.

Backbone.js Session Implementation Flow

I have a simple OAuth verification set up using Backbone, and it's working fairly well. My question is somewhat nitpicky (though... I am also new to Backbone), but I'm hoping to find somebody who might know how to solve this.
I have a Session model which, at initialization, sets a #authenticated value based on the presence of a value in localStorage. There's also a method in here, authenticate(), which checks the #authenticated value for pass/fail. If the value check fails, it uses my router to navigate to the login route. If the value check passes, an optional callback passed in by the user is run.
In my main AppView (the first View run at application start) I run Session.authenticate(), and if it passes, route to "#home" (and my Router handles loading additional Views).
My question is this: as an un-authenticated user, if I type http://url.com/#home into my browser, I am successfully routed to "#login", but if I bring up my DevTools, I can see a request being made for an image in my "HomeView" view. What am I not understanding about how Backbone flows through this process? Shouldn't the route for "#home" not even run until after the application initializes, and therefore not even attempting to load the "HomeView"?
What kind of templating engine are you using? If your templates are for instance inline, inside the HTML template where your backbone app lives, then I believe any images inside those are rendered when the page loads. I may be wrong. Also, ensure your HomeView is not running by logging something to the console in the view's initialize method.

Categories

Resources