I have an http request that grabs some data and applies it to a $scope variable:
$http.post("/api/division", 1).success(function(data){
$scope.division = data;
});
Now in my HTML I iterate through that data and display various bits of information, for example:
<div data-ng-repeat="player in division">
<div>{{player.name}}</div>
<div>{{player.number}}</div>
<div>{{player.score}}</div>
</div>
This works great. Now, I have a link that triggers a function to get a new set of data and bind it to the same $scope variable so the frontend will update with new information.
Get Division
$scope.getDivision = function(){
$http.post("/api/division", 2).success(function(data){
$scope.division = data;
});
}
Now, the front end does update with the new information, but there seems to be a lag of 5-10 seconds between the data successfully coming back and the HTML updating. So the problem isn't with the speed of the server. Is it something to do with needing to $emit or $broadcast the change to the variable? How can I get rid of the lag?
Related
I have looked up several posts with similar issue but was unable to find a solution for my case.
I have a search page that sends a request to the backend an populates the page with search results (each result is an object). I display a concise view of each object and, upon a mouse click on a specific object, the user should be redirected to a page that shows a more detailed view for that object.
On my JS side, I have one controller that handles the $http.post call and retrieves the objects from the backend to display on the first page. I use a different controller for the second page to try and get the relevant object from the first controller (through angular's .service ), but for some reason I get an empty object on the second page. The service works with a getter and a setter. The service is able to set the object just fine, through the first controller, and I am able to print it. However, when redirecting to the second page, while using the second controller's getter, the object gets deleted and shows as empty for some reason.
Here is the relevant code. The service:
app.service('shareService', function(){
var savedData = {}
function set(data) {
savedData = data
console.log(savedData);
}
function get() {
console.log(savedData);
return savedData;
}
return {
set: set,
get: get
}
});
The search (setter) contoller:
app.controller('SearchCtrl', function(shareService, $scope, $http) {
$scope.sendSearch = function() {
$http.post("http://localhost:9080/MedNetApp/rest/mednet/searchCollections", json).success(function (response) {
$scope.collections = response.searchResults;
shareService.set($scope.collections);
});
};
});
The second (getter) controller:
app.controller('CollectionsCtrl', function(shareService, $scope){
$scope.collections = shareService.get();
})
Not sure if this is relevant, but here is also the html part where I set up a temporary test button to redirect to the second page:
<button id=mixing type = "button" class="btn btn-primary-aligned"
data-ng-click = "go('second-page.html')">temp</button>
So, at the end, savedDatashows as empty object when printing it the second time through the get() function. Any idea why this is not working? or a better way to send data to a new page?
EDIT - I should mention that I basically relied on this solution:
AngularJS - Passing data between pages
So, after further research, I came across this solution:
Sharing Data between pages in AngularJS returning empty
I used sessionStorage in my service, as described in the link above, and it fixed the problem.
Use localStorage or sessionStorage
var myJson ={};
localStorage.set("your_Data",myJson);
// to get the value from another page
var returnJson = localStorage.get("Your_Data");
The usual start to these, I am new to both Ionic and Angularjs. I am developing an Ionic app which at it's heart is very simple. We show a list of classes(sessions), the person clicks on an icon to book the class then the icon changes to allow them to cancel the class. We also update the card to show the number of places remaining in each session on the day.
I have the code working to add and remove a person to and from a class but I am not sure how to update the template view from within the controller.
The controller code is pretty simple
// Check Person in to session.
$scope.addCheckIn = function(schedule){
var promise = sessionDataService.checkinSession(schedule.sessionID);
promise.then(function(data){
// Update (refresh) Schedule Details
// NOT SURE WHAT TO PUT HERE??
});
};
I have tried a number of different approaches including
Refreshing the $state and calling doRefresh and even calling the original controller methods to populate the cards again but the view won't update unless I physically click between states on the screen
//$state.go('app.schedules', {}, {reload: true});
//$scope.doRefresh();
//getScheduleData(formatDate(selectedDate), formatDate(selectedDate), 'true');
I have also looked at $scope.apply and $scope.timeout but I am not sure if this is taking me further from the real solution
What is the correct way to update the view after an update? Should it be after the promise.then in the controller or should I call a service and update everything.
Any tips on what is the best way to do this and a point in the right would be really appreciated.
Thanks everyone.
In your promise, you should add the data to the scope.
$scope.scheduledetails = data;
Then in your template, you will be able to access the object scheduledetails from the controller with AngularJS brackets to bind the data to the HTML.
<h1>{{scheduledetails.title}}</h1>
<p>Details : {{scheduledetails.details}}</p>
AngularJS should take care of refreshing what is needed without having to call any method or anything.
Full example
Controller
$scope.addCheckIn = function(schedule){
var promise = sessionDataService.checkinSession(schedule.sessionID);
promise.then(function(data){
$scope.scheduledetails = data;
});
};
Template
<h1>{{scheduledetails.title}}</h1>
<p>Details : {{scheduledetails.details}}</p>
On my page, I have a grid listing all articles returned by a web service. The user can go to a seperate page to add a new article and when finished, the article should be added in the grid on the other page. So when the user returns to that page, the article will be listed.
I have a service that handles the communication between the 2 controllers (one for the grid, one for the adding of articles). This service has a function called by the AddArticleController that broadcasts a message to my GridController:
function addNewArticle(articleNumber) {
$rootScope.$emit('newArticleAdded', {
articleNumber: articleNumber
});
}
The gridController picks this up:
$rootScope.$on('newArticleAdded', function(event, data) {
// get all article details generated by the back-end and add it to he grid
});
The problem is that, when the page with the grid has been displayed multiple times already, the article is added multiple times to the grid. I assume the reason for this is because every time a new controller is created, but the old controller is not being destroyed, so the broadcast is picked up multiple times.
How do I solve this issue? Obviously, the broadcast should only be handled 1 time.
Service
myApp.service('myService',function($controller){
this.broadcastEvent = function(){
scope = $scope.$new();
$controller('mainCtrl',{
$scope:scope
});
scope.broadCastMethod();
}
});
Controller
myApp.controller('mainCtrl',function($scope){
$scope.broadCastMethod = function(){
$scope.$broadcast("callBraodcast");
}
})
Acknowledging that I say this from a position of ignorance; would it not be easier to have the service maintain the list of articles and let the controller observe that? It would avoid the need to send messages back and forth through the scopes and have a single source of truth.
I am using Angularjs and trying to update my ui. Currently I am making use of these methods to update the ui quickly, but I am getting a 2 second delay before ui changes after controller has been updated with new data.
$scope.sub("panel.service.updateData", updateEventData.bind(this));
function updateEventData(ngEvent, data) {
var errorMessage = "updateEventData() ";
this.timeout(():void=> {
this.scope.list.myList = [];
this.scope.list.myList = data.data;
});
console.log(errorMessage+data.type);
console.log(this.scope.list.myList);
}
I have also tried:
safeApply() method wrapping around the changes in my controller as
well.
wrapping my data inside another object 'list'
updating the controller with a $watch()
updating the controller with sub/pub
I am currently using a sub/pub mechanism to pass data between controllers and services.
I have a console.log() set up right after the call in the controller to show when it was updated with new data, the controller is updated quickly, but my ui doesnt get the changes for about 2 seconds afterwards.
Any ideas?
Yes, you can force Angular to redraw "right now" by calling controller.$apply(). In your code I believe it would be:
this.timeout(():void=> {
this.scope.list.myList = [];
this.scope.list.myList = data.data;
this.scope.$apply();
});
I am using angularfire 0.5.0 to set a scope variable called tokenRate in one of my controllers and displaying the value of tokenRate in the corresponding HTML file like so:
Controller:
function TokensCtrl($firebase, $scope) {
$scope.tokenRate = $firebase(new Firebase("https://TEST_URL.firebaseio.com/token_rate"));
}
HTML:
<h1>Token rate is {{ tokenRate }}</h1>
I would expect the value to be displayed the first time and automatically update whenever "token_rate" is changed on the remote firebase. Instead, the tokenRate seems to be undefined initially and does not update when I change "token_rate" on the remote firebase.
The data sync is happening because I am able to receive "change" events from the remote firebase. I am guessing angularjs somehow doesn't know about the object change because putting a $watch on "tokenRate" doesn't trigger anything. I can get it to display the behavior I want by doing:
var value = $firebase(new Firebase("https://TEST_URL.firebaseio.com/token_rate"));
value.$on("change", function() {
$scope.tokenRate = value.$value;
});
But this seems ridiculous to do every time. I don't think I am understanding something here. What is the proper way to set the $scope.tokenRate variable so that it displays the first time and syncs automatically?