Angular js- Controller loads only on page refresh - javascript

$rootScope.$on("conv", function() {
var cobject = nservice.getconvo();
console.log("cobject", cobject);
$scope.cnotifications= cobject.convos;
$scope.num_unread= cobject.num_unread;
});
This function is inside a controller.That controller is loading up only on page refresh.Its fethching the data from service when on page refresh.

Well, the simplest solution will be to use events.
The service should have a method, which the controller calls, that tells the service to refresh the data (the notifications). Once fresh data is available in the service, the service will throw an event on the rootScope, which the relevant controllers will intercept, and update their models accordingly.

Related

How to pass Data from One Controller to Service and access that data on Other Controller on same event?

I'm facing some issue while trying to pass the data from one controller to the other using my service.
I've been implementing the prototype inheritance using the $rootScope in my controller and broadcasting that object, so that I can access that data in the other controllers.
As I'm using the $rootScope, I'm polluting the global namespace, I'd like to pass the data from this controller to the other.
I'm just displaying minimal data inside a table, when the user clicks on specific record of the table, I want to display entire data inside the object.
This is how I'm handling.
<tr ng-repeat="contact in filterContacts = (contacts.contactsData | filter:sensitiveSearch | orderBy:selectBox) " ng-style="{'background-color': contact.email == selectedContact.email ? 'lightgrey' : ''}" ng-click="selectContact(contact)">
In Controller A: I'm calling this function from view and injecting the specific row contact detail.
$scope.selectContact = function(contact) {
contactService.selectedContactInfo(contact);
};
In the Service I'm just returning that data -
var selectedContactInfo = function(contact) {
return contact;
};
How can I access this data in the Controller B during the same event and display it on my view.
Here is the reference Link: http://plnkr.co/edit/beOmiv?p=info
I don't want to use the $rootScope, but I'd like to access the data onto the other controller.
You could use an angular service for this.
The angular services are singletons and you inject them in controllers so you could inject the same service in two different controllers and you are effectively passing state between them.
Imagine you have a property in your service which could be called selectedUserID. You update this property when you click on the specific row. Then in the next controller, you inject the same service and use this property to determine which details you will load.
so you could have a method inside your service which could look like this :
updateSelectedUser = function(userID) {
this.selectedUserID = userID;
}
Your controller then calls this method from the service when the click action happens :
myService.updateSelectedUser($scope.selectedUserID);
This is just an example of course, put your own values in there.
One thing to keep in mind : services can hold state, they are objects after all and singletons so you always inject the same instance.
It makes sense to make sure that the state stored inside the service is not modified by outside actions which do not go through this service. In other words make sure that nothing else changes this selectedUserID so your service state data never gets out of sync. If you can do this, then you are golden.

Where to store remote data used by directive inside ngView? (AngularJS)

Just for example:
I have directive inside ngView with this structure:
.directive('features', function() {
templateUrl: '.../',
link: function(scope) {
// HTTP req, getting remote data.
// Store the remote data to the scope
}
})
When I change the route and return it back, the directive link option is executed again, the scope is empty. It need to wait some time for data-response from the remote server and then showing the data. I trying to avoid the layout stretching.
I am new to angular, I was read the documentation.
My question is: In this case, where the data is good to be saved? Do I need to make a controller? Or I can just cache it?
Note: This directive repeating an array (remote data) and making "features" HTML layout. This directive will be used in another routes with another behaviors.
I do not need code explanations, I can read docs. I accept terminology.
You could store the data in a service, basically to act as a cache as you mentioned. If you need to have that data available on page reloads (hard refresh, your app is reloaded again) you can store it in a cookie/local storage.
app.service("featuresService",function($http){
var cachedFeatures=null;
return{
getFeatures:function(callback){
if(!cachedFeatures){
$http.get("...").success(function(data){
cachedFeatures=data;
callback(data);
})
}else{
callback(cachedFeatures);
}
}
}
})

AngularJS Router invoke function when certain URL is loaded initially

I am using angular router` to track the state of my web app like this:
when('/', {
controller: "AController",
templateUrl: "APanel.html"
}).
when('/subpage/:id', {
controller: "BController",
templateUrl: "BPanel.html"
}).
And I am using Angular Service to track some shared values:
app.service('stateService', function() {
this.someSwitch = false;
this.someLongDataArray = [x, y, z];
});
Currently, before changing path to \subpage\:id url from AController, I will assign new values to members of the service, so they can be referenced in subpages.
Now the question is, if user directly launching the subpage url \subpage\:id, or hit the refresh button on browser on subpage, BController will be invoked, and I will lost the values in the service which are supposed to be prepared by AController.
I am wondering what I should do in this case. is there any way I can get called when user launch the subpage directly, so I have a chance to prepare the data? (Maybe I can watch for html onload event, but not sure that's the best answer).
Thanks
It appears, BController is dependent on AController.
Ideally, Controller should not contain any data/dom manipulaton, state maintenance. It is simply a glue between view and the $scope model.
Being said so, you need not create any such dependency between controllers. The service can be invoked from both controllers.
OR
If indeed there is a requirement that APanel.html must be loaded/initialized before BPanel.html is loaded, then you must check for some flag in BContoller and redirect user to APanel.html.
like
if(<check some flag>){
$location.path('/');
}
But then you have to find the way to redirect the user again to BPanel.html. I guess this is not a recommended approach.
I am not sure I get your question completely. But if there is a possibility that the user might hit BPanel.html directly then you should do something like this.
if(serviceExists()){
//Do your usual Bcontroller stuff here if the services was initialized
}
else{
//Show a warning/error like "Oops, something is wrong go back to '/'" OR
// Initialize services in BController
}
This should be in your BController if initializing your service before BController is that important. You basically force people to stay on AController.

angular how to use scope from a different controller

I have a user.list.ctrl and a user.detail.cntr. All the controllers are build as a module and are injected in a "user-module" which I inject in the app.js. (see the complete code in the plunker below)
my controller module
angular.module('user-module', ['user-module.controllers']);
my user-module
angular.module('demo.app', ['user-module']);
In both controllers i inject user-Fctr with data from a REST factory. (works well)
user.list.cntrl has a $scope.refresh()
user.detail.cntrl has a $scope.update()
user.list.cntrl
When I enter a new record, i call the $scope.refresh() so I can refresh the list. (this is working fine)
user.detail.cntrl
When i click a user from the list, the user detail loads in a different view (works ok)
when I update the user.detail, I want to call $scope.refresh() to update the user.list , but it is not working. I cannot call $scope.refresh()
I thought that since I inject the same factory into both controllers I can use each others $scopes.
Any ideas on how I can use $scope.refresh() (or update the list when I update the user.detail.js)
I make a plunker with all the js files (the plunker is not functional, it is only to show the code that I have)
http://plnkr.co/edit/HtnZiMag0VYCo27F5xqb?p=preview
thanx for taking a look at this
This is a very conceptual problem.
You have created a controller for each "piece" of view because they are meant for different activities. This is the purpose of controllers. So that is right.
However, you are trying to access the refresh function, written in one controller, in another one. Taken literally, this is wrong, since then, refresh is out of place either inside the user list controller or the detail controller.
A function that is meant to control (literally) what is happening on a specific piece of view is a controller. - There you are right having a controller for the list and one for the details.
A function that is meant to be shared between controllers must be a service. This is exactly what you want for your refresh function to be.
Whenever you inject the same factory into n controllers, you can't use the scope of every controller. This isn't the purpose of a controller.
However, whenever you inject the same factory into n controllers, you can use its exposed methods.
The problem you have, can be solved as follows:
app.factory( 'sharedFunctions', [ 'factoryId', function sharedFunctions( factoryId ) {
var refresh = function () {
factoryId.getAll(/*your params to query*/)
.success( function ( response ) {
//This will return the list of all your records
return response;
});
};
return sharedFunctions;
}]);
With this factory service registered, then you can inject it to your controllers and whenever you need to refresh, just call the exposed method of the service and plot the new information into the view.
Hope it works for you!
i ended up doing this:
I added in the list.contrl this:
factoryId.listScope = $scope;
since I already have the factoryId (my data service) injected in the detail controller, I can call this:
factoryId.listScope.refresh();
it works but I don't know if this is the best way. any comments?

$rootScope $broadcast working on two different controllers

I am trying to build a single page application where I have a setting form where I add a variable called Ticket Work type. When I do an update or save on the setting form, I am broadcasting the new Ticket Work Type array so that it reflects the listing as well as Ticket create page.
But the problem is that broadcast works only on the settings form page controller and not on the Ticket Add controller.
This is the code from the Settings controller where after "addTicketWorkTypes" factory method, I do a broadcast. This works :
$scope.addNewTicketWorkType = function(newticketWorkType) {
if (newticketWorkType != '') {
ticketFact.addTicketWorkTypes(newticketWorkType, $scope.workspaceId).then(function(response) {
$rootScope.$broadcast('handleTicketWorkType',response.data);
ticketFact.ticketWorkType = '';
});
}
};
And this updates the list on the same controller
/*update ticket work type when changes at any place*/
$scope.$on('handleTicketWorkType', function(events, ticketWorkType) {
$scope.ticketWorkType = ticketWorkType;
console.log('Scope updated settingsEditCtrl');
});
But the same $scope.$on doesn't work on a different controller. Can you please help.
The whole code is on Github for reference as well:
The settings controller is here: https://github.com/amitavroy/my-pm-tools/blob/master/public/assets/js/dev/settings/controllers/settingsEditCtrl.js
and the Ticket Add screen controller is here: https://github.com/amitavroy/my-pm-tools/blob/master/public/assets/js/dev/tickets/controllers/ticketAddCtrl.js
Any given scope will only be notified of events that are broadcast from a scope higher in the inheritance hierarchy. To send an event up the hierarchy use $rootScope.$emit().
If you want to be sure the event will be sent and received and you're not worried about other scopes responding to the event, you can do this:
function $broadcast() {
return $rootScope.$broadcast.apply($rootScope, arguments);
}
...
$broadcast('handleTicketWorkType', response.data);
In your other controller:
$rootScope.$on('handleTicketWorkType', function(data) {...});
If that doesn't work
It must be (as suggested by #charlietfl) that the target $scope does not yet exist and is hence not being notified of the event. In that case create a ticketWorkTypes service that is nothing but a list of ticketWorkTypes. Then replace:
$rootScope.$broadcast('handleTicketWorkType',response.data);
with
ticketWorkTypes.push(response.data);
Then inject ticketWorkTypes service (array) into any controller that needs that data.

Categories

Resources