AngularJS binding response from server not updating in view - javascript

I am developing a mobile application. I encountered a problem while trying to relay messages in the view that was returned from the server after an ajax call. The idea is to display the message in the view after the user clicks on a "Refresh" button.
The binding is not working exactly as I hope. It is not showing the user the current message but the one received from a previous click of the refresh button. Thus, the first time the user clicks the button after the view is loaded, nothing happens... I can't figure out why the view update is not instantaneous but rather only changes when the user clicks again.
Here is a simplified version of my code:
HTML:
<span ng-model="rec">{{rec}}</span>
<button ng-click="getNew()">
Refresh
</button>
JavaScript:
$scope.rec = window.localStorage.getItem('content');
$scope.getNew = function() {
$.ajax({
...
success: function(result, textStatus, xhr) {
...
window.localStorage.setItem('content', result.content);
$scope.rec = window.localStorage.getItem('content');
}
},
error: function(xhr, textStatus, errorThrown) {
...
}
});
};
I know that the ajax call is successful every time since the view is updated, but one step late of when it should be. Thanks for the help in advance!

There is no digest cycle after the ajax call is finished so the view does not get updated. If you use $http service instead of $.ajax. Then the view will get updated.
The code would look like this then:
$http({method: 'GET', url: '/someUrl'}).
success(function(data, status, headers, config) {
window.localStorage.setItem('content', data);
$scope.rec = data;
}).
error(function(data, status, headers, config) {
...
});
Of course you must inject $http to your controller.

Of course! You MUST use Angular $http service.
Read this article.

In order to do a http call, Ideally you need to create a factory for this kind of scenario. Factory which implements http will return a promise by default on which you can update your scope variable.
Syntax for factory would be:
myapp.factory('getHttpData',function($http){
return{
getData: function(){
return $http.get('/urlA');
}
}
});
and in your controller:
.controller('testCtrl',['getHttpData',function(getHttpData){
getHttpData.getData().then(function(data){
$scope.rec = data;//Whatever you want to store in this variable
});
});

Related

Abort HTTP request when redirect

I got this page which uses Angular and when the page is loaded, it requests some data from a HTTP get call. My problem is that if the user navigates to a other page while the HTTP get call is going on, the system gives a error and then gives me the HTTP error callback showing the alert with "Error".
$http.get('/api/something/).success(function (data, status, headers, config) {
alert(data);
}).error(function (data, status, headers, config) {
alert('Error');
});
What I want instead is to just abort the http call and then move the user to the other page without the error function being called.
So far I found this.
But I can't see how I can use it to fix my problem.

Angular $http.get with dynamic route?

I'm fairly new to angular and I'm trying to understand how to query from a REST API using a scope variable to determine the URI that is being pulled in the get request.
Lets say I'm in my app.controller and it has a service that spits out an array of numbers.. and for the sake of making the code minimal, I'll skip to the important part:
$scope.currentCompanyId = '0001';
$http.get('/api/'+ $scope.currentCompanyId +'/c').
success(function(data, status, headers, config) {
$scope.cData = data;
}).
error(function(data, status, headers, config) {
// log error
});
I know this is cheating because the $http.get is in the controller. I know it needs to be a factory of some kind.. but I have no idea how to pass the $scope.currentCompanyID to the get request and have it return the JSON. Furthermore, if $scope.currentCompanyID were to change to another number, say... '0002'.. how would the $scope.cData change to reflect the new query?
I don't think using $http in your controller is cheating - one reason for putting it into a factory/service is make it reusable. If you are only doing it in one place a service doesn't add much.
That being said, your service can return a function that takes a parameter:
app.factory("service", function($http) {
return {
getCompany: function(companyId) { ...make $http call and return data... }
}
});
then in your controller:
service.getCompany($scope.currentComanyId).then(function(resp) {...})
You should consider using Angular $resource because it handles a lot of your abstractions. Either way, if you want to make a new request based on changes in the scope variable, you can $watch it:
$scope.$watch('currentCompanyId', function() {
if(!$scope.currentCompanyId) return;
$http.get().success(); // replace with whatever mechanism you use to request data
});
Your request wont launch if currentCompanyId change... You need to lauch your request manually .
otherwise, it seem to be correct
Did you look at $resource service? http://docs.angularjs.org/api/ngResource/service/$resource - it is rather convenient way to REST requests, and docs have quite a few examples that should suit you well
About changing $scope.currentCompanyID - it seems that you need to create watch for this case:
scope.$watch('currentCompanyID', function(newValue, oldValue) {
// do your update here, assigning $scope.cData with the value returned
// using your code:
$http.get('/api/'+ $scope.currentCompanyId +'/c').
success(function(data, status, headers, config) {
$scope.cData = data;
}).
error(function(data, status, headers, config) {
// log error
});
});
You simply need to pass the data in when calling your service. In your controller, you would need to include your service as a DI module and address it as so:
window.angular.module('myControllerModule', [])
.controller('myController', ['$scope', 'myHTTPService',
function($scope, myHTTPService){
$scope.currentCompanyId = 1;
$scope.lookupPromise = myHTTPService.get($scope.currentCompanyId);
$scope.lookupPromise.then(function(data){
//things to do when the call is successful
},function(data){
//things to do when the call fails
});
}]);
In your service, you deal with that value like this:
window.angualr.module('myHTTPServiceModule', [])
.factory('myHTTPService', '$http',
function($http){
function callHTTP(url){
return $http.get('/api/' + url + '/c');
}
return {
get: callHTTP
};
});

Updating models in controllers with AJAX Angular JS

I am sure this is an easy answer but I am not finding it anywhere. Essentially I have a $http service that brings back a JSON object with a ton of data that I need to use like so:
(function (angular) {
angular.module("forecasting").factory("DataServices", ["$http", function ($http) {
return {
//get forecast of entity
getForecast: function (callback) {
$http({
method: "GET",
url: Forecasting.urls.entityAPIRoot + "forecast/1722"
}).success(function (data, status, headers, config) {
callback(data);
}).error(function (data, status, headers, config) {
callback(data);
});
}
}
});
} (angular));
This is just a service that takes a call back so the data can be saved to the scope like so:
DataServices.getForecast(function (data) {
$scope.forecast = data;
});
This works well when trying to show the data in the view, it updates like you think it would. However simply trying console.log($scope.forecast) placed after the above code in my controller does not work.
I want to be able to take subsections of the data so I can use it in my app, however, I can't access $scope.forecast so I am not sure how I am able to.
I have looked at other solutions that use $scope.$apply() and promises. I am just kind of lost and not sure where to go from here.
How do I access a subset of the data being saved to the $scope outside of the callback?

Angular $http call not binding on success to $scope.data?

Im having an issue with the $scope.items=data when calling success. I am using this jsfiddle : http://jsfiddle.net/SAWsA/11/ However instead of hardcoded items I did this:
$scope.items=$http({method: 'GET', url: '/test/database/two'}).
success(function(data, status, headers, config) {
return data;
}).
error(function(data, status, headers, config) {
$scope.status=status;
});
and tried this:
$http({method: 'GET', url: '/test/database/two'}).
success(function(data, status, headers, config) {
$scope.items=data;
}).
error(function(data, status, headers, config) {
$scope.status=status;
});
When I put an alert within the success function I see the lenght being 25, so I know i am getting the data. However when I check the $scope.items after this $http run, I get a lengh of undefined after I leave the success function. Like it sets itself and loses it set outside of scope? Any help much appreciated.
When $http runs it will immediately return either [] or {} depending on whether isArray is set or not. The functions you pass to success or error are executed at a later time, when the data is received. When this data is received the [] or {} you had earlier will be populated with the data.
It sounds like you are running $http and testing for the data before it has had chance to be retrieved from the server. If you want to use the data then your relevant code should probably be inside the success function to defer the work until you have the data you want to work with..

In Angular JS application, how do you handle the cases where there is no response from the server?

Lets say I have a route set up like so:
$routeProvider.
when('/myroute', {templateUrl: '/views/RouteA.html', controller: 'AController'}).
otherwise({redirectTo: '/home'})
If the server is down, when I click a link to "http://myapp.com/#/myroute" I can see that the requests to load the RouteA.html file are timing out. However, to the user, the application just sits there leaving them with no indication of a problem. I don't see any clear explanation anywhere for handling this type of non-response.
The Best way to tackle this is to add routeChangeError event
$rootScope.$on("$routeChangeError", function () {
alert("there is some error");
//do what ever you want to do again
});
Maybe this cant be a hint for you...
$http({method: 'GET', url: '/someUrl'}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});

Categories

Resources