Data is not working outside the request function in AngularJS? - angularjs

How to can access $scope.categories outside the promise success function
var categoryPromise = $http.get("../rest/mcategory");
categoryPromise.success(function(data, status, headers, config)
{
$scope.categories=data;
});
categoryPromise.error(function(data, status, headers, config)
{
alert("Error");
});
alert(JSON.stringify($scope.categories));
I got undefined in each time Why? Any way to access outside?

A $http call is asynchronous, this means that it doesn't execute in order of your code, the actual order of your code is as following:
Initialise categoryPromise $http
alert
categoryPromise finishes
categoryPromise success callback
So if you want to use the data from categoryPromise you have to do it in the success callback.
Side note: don't use .success, it's deprecated. Use .then instead like so:
promise.then(successCallback, errorCallback);

As Martijn points out, if you want to use it for direct modification you'll have to do it into the callback as the XHR request won't be finished.
However if you put this into your $scope, it's maybe because you'll use it into your view with data binding into the DOM. In that case Angular is pretty neat because, when the promise will be resolved, at the next $digest cycle it will populate with your category object all of the {{category.strings}} in your $scope realm.
Would love to post that in a comment but don't have 50 rep.

The problem here is angular hits that url and continues to execute the code after that without waiting for response that's why here maybe url is hit by browser but when execution reached to assign categories it got undefined.
Solution:
var categoryPromise = $http.get("../rest/mcategory");
categoryPromise.success(function(data, status, headers, config)
{
$scope.categories=data;
alert(JSON.stringify($scope.categories));
});
categoryPromise.error(function(data, status, headers, config)
{
alert("Error");
});

Related

How to display response data ($http) from server in AngularJS

How to display reponse data (get) from server in AngularJS
in my code I need to alert $scope.orders inside that controller but it willll not show..
function OrderController($scope,$http)
{
var orderPromise = $http.get("../api/order");
orderPromise.success(function(data, status, headers, config)
{
$scope.orders=data
alert(JSON.stringify($scope.orders)) // First alert
});
orderPromise.error(function(data, status, headers, config)
{
alert("Error");
});
alert(JSON.stringify($scope.orders)) // Second alert
}
How can i access $scope.orders to outside the success fun()
Here I am alerting $scope.data in two times
In here First Alert is shown
but Second Alert is nothing to show why?
How to show second one?
Second alert will not show because there's nothing in $scope.orders when you alert it. That's the nature of asynchronous calls, only when you enter the success/error sections will you have something there (or not...).
Until the server returns your response and the success/error functions trigger, that variable is still unpopulated since $scope.orders=data hasn't run.
You should read the docs for some more info, and get some deeper understanding into how promises work.

Angularjs $http for YQL not working?

I am a newbie angular js developer. Recently i am trying to build an application that uses Yahoo Query Language (YQL). I actually need the cricket.teams data from the data table. So, i am just making a $http resquest from the controller of the angularjs with the REST Query provides by Yahoo.
Here i my view:
<div ng-controller="ProfileCtrl">
<div style="height:80vh">
{{Hello}}
</div>
</div>
Here is my controller
app.controller('ProfileCtrl',function($scope,$http){
$scope.Hello='Welcome';
var url ='https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20cricket.teams&format=json&diagnostics=true&env=store%3A%2F%2F0TxIGQMQbObzvU4Apia0V0&callback=';
// Simple GET request example :
$http.get(url).
success(function(data, status, headers, config) {
alert(data);
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
alert('error'+status);
});
});
It is returning Error with the status 0. that means there is somehow an error. what i am doing wrong here ??
NB. i have tried with $http.jsonp() . and its giving the same result.
If you are getting status 0 then it might be due to illegal cross-origin request https://stackoverflow.com/a/10910212/1061668
Despite that your code is fully functional, see related plunker here http://plnkr.co/edit/xFAnI7
Following api call
$http.get(url).then(function(response) {
$scope.response = angular.toJson(response.data);
}).catch(function(response) {
$scope.response = response;
});
Will return something like
{"query":{"count":14,"created":"2015-05-05T10:38:27Z","lang":"fi-FI","diagnostics":{"cache":{"execution-start-time":"0","execution-stop-time":"3","execution-time":"3","method":"GET","type":"MEMCACHED","content":"TABLE.yql-query-yahooapis-com.v1.production.manhattan.bf1.yahoo.com.cricket.teams.cb28f8540307fdb68289fa5fedc2b832"},"url":[{"execution-start-time":"4","execution-stop-time":"9","execution-time":"5", ... etc etc

angular-http-auth with $http transformResponse

I'm using angular-http-auth to show a login dialog whenever a 401 "unauthorized" response is returned from the server.
Since I'm cool, I also try to deserialize response objects in my services. For example, if a service requests a car and the response is {make: Honda, model: Civic}, I try to deserialize that into a Car object using transformResponse.
For example:
getCar: function() {
return $http.get('/api/car', {
method: 'GET',
transformResponse: function(data, headers) {
var c = angular.fromJson(data);
return new Car(c);
}
});
}
This doesn't work with angular-http-auth. If the response was a 401 Unauthorized, you'll get a javascript error. It's because angular will try to run that transformResponse code even if the response was a 401.
It turns out that $http interceptors (which is what angular-http-auth uses) are run AFTER the transformResponse code. That's a huge problem, because none of that code in transformResponse will work if the server response was a 401 (there wouldn't be any data)
Is this a problem for anyone else? How did you get around it? Am I not to use transformResponse if I use $http interceptors?
Late to the party, I know, but to anyone coming here from Google like I did (I also posted this as a comment on a related issue filed with the Angular repo):
I also found it to be confusing that response interceptors run after the transformResponse method. I added a method to $http.defaults.transformResponse. Here is an example from the documentation on how to do that.
So, if you need to basically have a response interceptor that runs before the transformResponse method, this should do it:
'use strict';
angular.module('app')
.run(function ($http) {
$http.defaults.transformResponse.push(function (data, headers) {
// do stuff here before the response transformation
// Be sure to return `data` so that the next function in the queue can use it.
// Your services won't load otherwise!
return data;
});
});
If your services or http calls don't have their own response transformer, you're good now.
If your services do have their own transformResponse method, they will actually override all default transformers (I found this out after a long read of the documentation), and the above code will not run.
To circumvent this, you can follow this example in the docs.
To get around this problem I don't use transformResponse anymore. I just can't see the point of transformResponse if it runs before $http interceptors.
In order to use angular-http-auth and also deserialize responses in your services, you can write your services so that they execute the HTTP request first and then deserialize the response in a callback function.
As an example, here is how I would have restructured the example in the OP:
Plunker
services.factory('HttpCarService', function($resource, $q) {
var resource = $resource('/api/car');
return {
getCar: function() {
var deferred = $q.defer();
var car = null;
var successCallback = function(data, status, headers, config) {
var c = angular.fromJson(data);
car = new Car(c);
deferred.resolve(car);
};
var errorCallback = function(data, status, headers, config) {
deferred.reject("something wrong");
};
var result = resource.get(successCallback, errorCallback);
return deferred.promise;
}
};
});
This pattern will also work if data is an array.
$http interceptors will run before either of the callback methods are executed. If your $resource needs url params, you can make the getCar() function accept a config object as a parameter, and pass the necessary information on when you make the $resource.get() call.

Exception handling with jsonp requests in angularjs

I have the following code which make seperate requests for jsonp data.
In the code "doRequestA" works fine and returns a result. The issue I have is
I need to catch any errors if they occur. I have tried implementing this in
"doRequestB", but only receive the alert error (I have ommitted the callback from doRequestB).
Here is the fiddle http://jsfiddle.net/a4Rc2/417/
function jsonp_callback(data) {
alert(data.found);
}
function jsonp_example($scope, $http) {
$scope.doRequestA = function () {
var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=jsonp_callback";
$http.jsonp(url);
};
$scope.doRequestB = function () {
var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts";
$http.jsonp(url)
.success(function (data) {
alert(data.found);
}).error(function (data, status, headers, config) {
alert('error');
});
};
}
Any advice is greatly appreciated, thanks in advance.
You actually are using $http.jsonp incorrectly in both cases. You just can't see the error in the first case because you are not handling it.
With Angular.js's $http.jsonp method, the callback method is handled automatically. You shouldn't use your own methods in the result string, but rather insert JSON_CALLBACK (exactly as written) into your string. This way, you can handle the response using the promise returned from Angular. If you watch the network activity (say, using Firebug or the developer tools in your browser of choice), you'll see JSON_CALLBACK replaced with something like angular.callbacks._0*.
In the second example, you don't have a callback method defined at all, so the result will always error. There's actually no way for the jsonp result to be handled, since it simply returns the JSON object without a callback method, and the result just is ignored.
Here's a working result: http://jsfiddle.net/tPLaN/1/
The code:
function jsonp_callback(data) {
alert(data.found);
}
function jsonp_example($scope, $http) {
$scope.doRequestA = function() {
var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=JSON_CALLBACK";
$http.jsonp(url).success(function(data) {
jsonp_callback(data);
});
};
$scope.doRequestB = function() {
var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=JSON_CALLBACK";
$http.jsonp(url)
.success(function (data) {
alert(data.found);
}).error(function (data, status, headers, config) {
alert('error');
});
};
}
The only thing I changed was
Correcting the two URLs.
Moving the callback handler on the first method inside the .success() method on the promise.
Believe it or not, the need for JSON_CALLBACK is in the documentation for $http.jsonp, but it's sort of hidden.
* Note, please do not use the replacement for JSON_CALLBACK for anything. It's a private method generated by Angular, I am just showing it to help make more sense of what is happening.

use promise to get only portion of ajax response

The tutorial and docs show this very convenient syntax for AJAX calls:
$scope.myvar = $resource(/*blah blah*/);
Is there a way to use this syntax (instead of having to create a new successfn every time) if my API doesn't return myvar but something like {"myvar": myvar}?
UPDATE: Ah, now I think I got what you're after: You want to have the empty reference (placeholder) for a field of the returned object, in a call like this:
var User = $resource('/user/:userId', {userId:'#id'});
Am I right?
If so - I think the easiest way is simply to bind to the object's field (aka {{user.myvar}}).
Well, the success function is called only once (and if) the data has been received successfully. The function is called with the fetched data given to it as an argument and you can access it no matter its structure. You can reuse a function instead of defining one inline, of course.
So instead of this (example from Angular docs):
$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.
});
You can use:
function myHandler(data) {
// Do something with data.myvar ...
}
$http({method: 'GET', url: '/someUrl'}).success(myHandler);
Hopefully this helps, but very possibly I did not get what exactly you're after :) Let me know.
Relevant documentation.
You need to call get() or query() on your resource to make an actual AJAX request. If you don't want to assign the full result of the server API directly to some ($scope) variable, then you have to write the success function.
var SomeResource = $resource('/blah/blah');
var theResource = SomeResource.get({optional params here}, function() {
$scope.myVar = theResource.myVar;
}
or
var SomeResource = $resource('/blah/blah');
SomeResource.get({optional params here}, function(theResource) {
$scope.myVar = theResource.myVar;
}
Or do what #Chasseur recommends -- assign the full result then bind to the appropriate field in your view:
var SomeResource = $resource('/blah/blah');
$scope.theResource = SomeResource.get({optional params here});
Then in HTML use {{theResource.myVar}}.
Also, $resource, unlike $http, does not return a promise. Update: in newer versions of Angular, $resource now exposes a promise.

Resources