UI not updating after ajax fetch - angularjs

I have this code for a restaurant app:
// Select date and load resources
$scope.selectDate = function (date) {
$scope.dateInActiveSelection = date;
loadMenuFor(date);
};
// Load daily menu for given date.
function loadMenuFor (date) {
DataApi.dailyMenu(date, function (response) {
console.log('Loaded menu for ' + date.toString());
$scope.menuItems = $scope.originalMenuItems = response.data;
});
}
I am fetching new menu for every day the user selects with this method:
// Select date and load resources
$scope.selectDate = function (date) {
$scope.dateInActiveSelection = date;
loadMenuFor(date);
};
But the UI isn't updating. I have one {{ menuItems.length }} displayed and another ng-repeat neither of which are getting updated.
I tried $scope.$apply() as mentioned in other answers but I get a in-progress error, even when I try it inside a $timeout.
Where am I going wrong ?

I found out the problem. There were two elements with the asking for the same controller. One was the date chooser element and another was the one with the item listing. So, whenever I was choosing the date, the scope was getting changed.

Related

Search method to show record before data update in sql server Angularjs asp.netmvc

Angular js function updating some record. After updating record i am calling search method to show data on view.
But record does not updated before that search method call that does not get data so show null on view.
I have separate button for search on its ng-click this search method call. After some second if i click that button it shows data on view.
my code is,
vm.Update = function (value)
{
var test = value;
searchCriteria = {
From: vm.From,
To: vm.To,
Region: vm.Region,
City: vm.SelectedCity
}
surveyService.UpdateVisit(searchCriteria,value).then(function (d) {
var Confrm = JSON.parse(d.data.data);
if (d.data.status) {
toastr.success(Updated, {
autoDismiss: false
});
}
else {
toastr.error(errorMsg);
}
});
vm.searchVisit(0);
}
This searchvisit call and service unable to update data in database so i do not get any record on view. When i call this searchvisit method from separate button for searching it shows record with updated data.
Hopes for your suggestions how to pause execution before calling searchvisit method or any alternative that it gets any response than move execution control to searchvisit method.
Thanks
This is due to the asynchronous nature in JS.
From your code, surveyService.UpdateVisit(searchCriteria,value) returns a promise. Thus, when vm.searchVisit(0); is called, surveyService.UpdateVisit(searchCriteria,value) has not been resolved yet, meaning updating is still in progress and have not been completed. There for vm.searchVisit(0); shows records that are not updated.
If your second function is dependent on the values of the first function call, please add it as shown below inside the success callback.
surveyService.UpdateVisit(searchCriteria,value).then(function (d) {
var Confrm = JSON.parse(d.data.data);
if (d.data.status) {
toastr.success(Updated, {
autoDismiss: false
});
}
else {
toastr.error(errorMsg);
}
//Add this here.
vm.searchVisit(0);
});

Angular js watch for value in two fucntions

I want to update my data based on data received from back-end
there are two functions:
function getData(data){
Service.getRequest(url).then(function (_response) {
console.log(_response)
var res = _response
if(res.data.success) {
$scope.$watch('data.photo', function() {
alert('hey, myVar has changed!');
});
data.photo = res.data.result;// this will tell that Image received against the corresponding data
}
else {
ctrl.errorCallBack = true
ctrl.errorFunction = 5
}
$rootScope.showPreloader = false;
});
}
now I have second function that receives the selected data and called when clicked on button , now question is can I update the data inside this function when above Get request is completed:
function syncData(data) {
console.log('image received')
console.log(data)
}
First function is called n times based on number of images , now user click on second function to view Image but user don't see any Image because Image is not received yet but I want a way to update second function as Image is received
examples
ist image is loaded....user doesn't click on second function
2nd image is pending....user clicks on second function or second function is active
2nd image is received....active function image received
https://plnkr.co/edit/zKeDT84W6eF9cc3FpcmG?p=preview
If you use $scope for variables they will be automatically sync with DOM whenever it changes.
I did some changes for you in plnkr i hope solve your problem.
http:// plnkr.co/edit/Ug53a03kB7Ap1EWf2jZK?p=preview

How to refresh Graph Input data in Angular 2

I am using some Graph view to view some statistic in my project.
e.g. Morish Grapgh, Pie chart graph.
I have an option like date range, so that I can specify the range of date and can fetch the data within that range and show the output graph in the front end.
The issue I am facing is at the First time I am able to see the out put while I am changing the Date range.
from the second time I am able to get the Data from the backend but after setting the new set of values to the graph Data, but the graph view is not changing because the graph is not able to refresh.
Here sample code. Please ask if any additional info needed.
<sa-morris-graph *ngIf="graphData!=null" [data]="graphData"
type="area"
[options]="{
xkey: 'x',
ykeys: ['y', 'z'],
labels: ['USER', 'New USER']
}"></sa-morris-graph>
from the Component type script file I am setting graphData
export class GAUserComponent implements OnInit{
fromDate : any ;
toDate : any ;
graphData : any = null;
dateSelected(){
this.gaService.getGaData(this.req,"/users")
.subscribe(
data => {
this.dataResponse = data;
let grData = [];
for (let data of this.dataResponse.usersByDate) {
var sample={"x": data.valueX ,"y": data.valueY , "z" : data.valueZ };
grData.push(sample);
}
this.graphData = grData;
},
err => {
console.log("Error occered : "+ err);
}
);
}
Please suggest me to solve the problem.
I guess In angular 1 there is a watch() to achieve this but in angular 2 this function is not there.
correct me If I am wrong and help me solve this
Thanks

Filter data by user with angularfire

I'm using angular-ui-fullcalendar to show and edit events. Users can log in and have unique uid when logged in. I want to use this to distinguish events made by current user from other events. I want to give current user events another backgroundColor.
What is the best way to do this??
I tried several things. My data looks like this:
```
database
bookings
-KWnAYjnYEAeErpvGg0-
end: "2016-11-16T12:00:00"
start: "2016-11-16T10:00:00"
stick: true
title: "Brugernavn Her"
uid: "1f17fc37-2a28-4c24-8526-3882f59849e9"
```
I tried to filter all data with current user uid like this
var ref = firebase.database().ref().child("bookings");
var query = ref.orderByChild("uid").equalTo(currentAuth.uid);
var bookings = $firebaseArray(query);
$scope.eventSources = [bookings];
This doesn't return anything. If I omit the filter in line 2 it returns all bookings as expected. But even if the filter worked it would not solve my problem, because I want to fetch both current user events and all other events. Firebase does not have a "not equal to" filter option...
I tried to loop through each record and compare uids and setting backgroundColor if condition was met:
var ref = firebase.database().ref().child("bookings");
var bookings = $firebaseArray(ref);
bookings.$ref().on("value", function(snapshot) {
var list = snapshot.val();
for (var obj in list) {
if ( !list.hasOwnProperty(obj) ) continue;
var b = list[obj];
if (b.uid === currentAuth.uid) {
b.className = "myBooking";
b.backgroundColor = "red";
}
}
});
$scope.eventSources = [bookings];
But this causes asynchronous problems so the 'bookings' array assigned to $scope.eventSources wasn't modified. I tried to move the $scope.eventSources = [bookings] inside the async code block but FullCalendar apparently can't handle that and renders nothing.
I also tried this but no luck either:
bookings.$loaded()
.then(function(data) {
$scope.eventSources = [data];
})
.catch(function(error) {
console.log("Error:", error);
});
What is the best solution to my problem?
If you're looking to modify the data that is loaded/synchronized from Firebase, you should extend the $firebaseArray service. Doing this through $loaded() is wrong, since that will only trigger for initial data.
See the AngularFire documentation on Extending $firebaseArray and Kato's answer on Joining data between paths based on id using AngularFire for examples.

One way binding angularjs

I have a list of employees in a select, where the user can pick an employee and edit its details. Then he triggers an ajax call through a button, so the server can update the record in the DB.
I am binding with ngModel the fields and the data from my list of employees, but it is problematic if the update fails on the database side, because my list of employees is updated through the two way binding.
Is there a way to initialize my fields when the user picks an element in the select and update my employee list only when I get response?
Here is my explicit code from my directive (view):
select(ng-model='selectedEmployee' ng-options="employee.name for employee in employees")
form(role='form')
input(type='input' ng-model='selectedEmployee.userId')
input(type='input' ng-model='selectedEmployee.name')
button (type='button' ng-click='updateEmployee()') update
and the directive
app.directive('employeeList', ['employeeServices',
function(employeeServices) {
var employeeListController = function($scope) {
employeeServices.getEmployees()
.success(function(result) {
$scope.employees = result.data
})
.error(function(err) {
})
$scope.selectedEmployee = null
$scope.updateEmployee = function() {
employeeServices.updateEmployee({
userId: $scope.selectedEmployee.userId,
name: $scope.selectedEmployee.name
})
.success(function(data) {
//I want to update my $scope.employees here
})
.error(function(data) {
//Otherwise I show some error message
})
.then(function() {
$scope.selectedEmployee = {}
})
}
}
return {
...
controller: employeeListController
}
}
])
Solution
So in order to solve the problem I used angular.copy along with ng-change. I've added ng-change to the select, where I copied the selectedEmployee to selectedEmployeeDirty that I supplied as model for my form. Then in the service's callback I updated the selectedEmployee.
Very simple. Object, in javascript, are shared throught a "reference".
In fact, this is a C pointer - or something like that -, how share the memory location of your object.
If you do this:
var a = {},
b = a;
a.toto = true;
console.log(b);
You will see
b = { toto: true }
Keep that in mind.
Now, how can we isolate your edited object, without updating the original one? Make a copy! angular.copy is a friend, and would duplicate every properties of src to the dst.
Use the ng-model as you did, save change, and, only on callback, update the original one :-)

Resources