Will callback functions be called if scope is destroyed in angular js? - javascript

We are following this pattern in which every function requesting to server is written in a service in angular application.
Then in controller we call that function like this -
suppose- service name is - homeService
then we use it like this -
homeService
.getUserName()
.then(getUserNameSuccessCallback, getUserNameErrorCallback);
I wanted to know if the server request is taking long and the user goes to other state, like home to profile so home controller would be destroyed and profile controller would be initialised,would the callback be still fired if the request to server is returned.

Related

AngularJS Calling function in controller after data is loaded in another file

I have this function in app.js which connects to an api using promises. The app that is selected to be opened depends on the user ID.
me.boot = function () {
me.getUserID().then(me.openAppFunction);
};
Also, I have this function in my Home.js controller
getObjectsFromApp();
This function needs to be executed after the application is loaded in the other file, but I have no idea how to do this. This app.js file is not a service or a factory, it is just a file that is called when the application loads all the scripts with require.js. The only thing this file does is select which app to open in the api, so that is why it is only called once.
An Event is probably what you are looking for...
You should stay in the angular environment, so, you should use $rootScope.$broadcast and $rootScope.$on and they can be used everywhere in your application because $rootScope is singletone.
this Why do we use $rootScope.$broadcast in AngularJS? could help you.

Change to admin view on successful login in angularjs application

I've a MVC application with nodejs and angular js as front end, I've a login page which have a different top menu than other pages
How to switch between these header to show in the view
In angular js login controller, I'm calling the service which checks for username and password returns JWT token if the login is successful. Everything is fine, But how to render the admin page
I wanted to know how to change the entire view rather than changing the the part of the view in angularjs
You should use promise and $location, or ui-router. When you post request to your server you can define success callback in your promise. Inside that callback everything what you need is redirect user. for example:
$scope.auth = function(credentials) {
myService.login(credentials).then(function(res/*response*/) {
$location.path('/');
or $state.go('app.dashboard');
}
}

Code organization (node, js involving models, service, route and mocha tests)

I'm quite a beginner in the project architecturing / structuring side of things.
The overall project currently looks like:
route/home.js
service/appService.js
models/appModel.js
In the route file, I require appService.js.
appService.js takes care of some API calls to external services, such as getting an access_token from such API service.
When I receive the access token, a callback is made in appService which calls appModel (appService requires appModel.js), and in turn appModel stores the access token in the database. Then, another callback is called in appService which in turn does runs the callback that the route page provided, then I make a redirection.
I am using mocha for testing the service and model files.
My service file is requiring the model file, so when I create a mocha test for the service file, the model is called indirectly as well.
Should I require the model in my route file instead of the service file, and run the model function in the route, once I receive the access token response from the API in the service file? What do you suggest?
Normally you would have some kind of bootstrapper or service container which handles loading your files.
That way you avoid tight couplings between the different parts of your application and can exchange them out when testing (such as swapping the DB for fixtures).

Syncronizing Session data with other angular directives and controllers

In my AngularJS application, I have a Session service object that contains stuff like the current user, their preferences, the current company they belong to, and the current theme that they are using. Many places in my application refer to the Session service when they need to get at this data.
Because these variables are in a service, I cannot use scope watches to detect changes. So instead, I've decided to use the observer pattern. Various places in the application, such as other services, directives, controllers, etc. will register themselves with the Session service and provide a callback to be executed whenever the Session changes.
For example, if the user changes their theme, the <style> element in index.html that uses a custom directive will be notified, and it will recreate all of the overriding css rules for the new colors.
For another example, whenever the user's avatar is updated, the main menu bar controller will be notified to refresh and redraw the avatar. Stuff like this.
Obviously the data in Session has to be refreshed at least once before the various controllers, directives, etc. use it. The natural place to ask the Session service to get its session data was in a run block for the application-level module. This works pretty well, but I don't think it's the best place either.
One problem I have noticed is that when Firebug is open, the asynchronous nature of things loading causes ordering issues. For example, the directive that runs on the <style> element will run AFTER the Session service has refreshed in the application's run block... which means the theme will not get updated after pressing F5 because the callback is registered after the initialization of the data occured. I would have to call a manual refresh here to keep it in sync, but if I did that, it may execute twice in the times where the order is different! This is a big problem. I don't think this issue is just related to Firebug... it could happen under any circumstance, but Firebug seems to cause it somewhat consistently, and this is bad.
To recap... This asynchronous ordering is good:
Theme Directive registers callback to Session
Menu Bar application controller registers callback to Session
Session.refresh() is called in .run block.
This asynchronous ordering is bad:
Menu Bar application controller registers callback to Session
Session.refresh() is called in .run block.
Theme Directive registers callback to Session, but callback does not get executed since Session.refresh() was already executed.
So rather than use the observer pattern, or refresh the Session state via a run block, what the best way to design the services, etc. so that the session data will ALWAYS get refreshed after (or maybe before) the various other parts of the application require it? Is there some kind of event I can hook into that gets executed before directives and controllers are executed instead of the run block?
If my approach is generally sound, what can I add to it to really make it work the way it should?
Thanks!
In angular.js you have 2 way of using global variables:
use a $rootScope
use a service
Using $rootScope is very easy as you can simply inject it into any controller and change values in this scope. All global variables have problems!
Services is a singletons(What you need)!
I think in your case you can use
$rootScope
And
$scope.$watch
Great answer
Is there a reason you can't access the variables directly like this:
app.factory('SessionService', function() {
var items = {
"avatar": "some url"
};
return items;
});
var MainController = [$scope, 'SessionService', function($scope, SessionService){
$scope.session = SessionService;
$scope.modifyAvatar = function(url){
$scope.session.avatar = "some new url";
};
}];
var HeaderController = [$scope, 'SessionService', function($scope, SessionService){
$scope.session = SessionService;
// You probably wouldn't do this, you would just bind
// to {{session.avatar}} in your template
$scope.getAvatar = function(){
return $scope.session.avatar;
};
}];

Chaplin js permanent controller that responds to routes

Is it possible to have a controller that keeps its state alive and also responds to routes?
For example I would have a PlayerController that I initiate in the application's initControllers method and then I will need it also to respond to a route like /player/trackID so I can change the current playing track.
Yes, you can create a controller which will be active for the lifetime of the application. As you mentioned instantiate PlayerController in initControllers method of the application and in routes.js define the route /player/:trackID to be bound to a specific method of the PlayerController.
e.g. route in routes.js will look like
match('player/:trackID', 'player#playTrack', {name:'playtrack'});
In the above route playTrack is the method of PlayerController.

Categories

Resources