Reading a angularjs promise object? - angularjs

I have a service that returns a study object as shown:
$scope.study = StudyService.studies.get({id: $routeParams.studyIdentifier});
When I print out the study object using:
console($scope.study);
I get this message on the chrome console:
Resource {$promise: Object, $resolved: false, $get: function, $save: function, $query:
function...}
So how do I read this study object. I like to be able to print its contents. For instance study has an id, and a list of cases. I like to be able to print:
console.log(study.id);
console.log(study.cases.length);
How do I accomplish this?

I assume that since you are receiving a promise as a response from your service you are using 'ngResource'. If so, then here is some documentation on using that module and how to handle the objects it returns.
https://docs.angularjs.org/api/ngResource/service/$resource
For your example though, you would need to just do the following
StudyService.studies.get({id: $routeParams.studyIdentifier}).$promise.then(function(study) {
$scope.study = study;
});
Hope this helps!

Related

How to loop through $resource returned query and get desired value?

I am using MEANJS
In my controller i have
// Find a list of Cars
$scope.findHome = function() {
$scope.cars = Cars.query();
console.log($scope.cars);
};
Which outputs
here i want to get the _id string inside the first array 0: Resource
I tried $scope.cars[0]._id which returns undefined, Please help.
You are inspecting the results of the query immediately after the call, but ngResource is asynchronous, so perhaps the data has not yet returned from the server by the time you are trying to access it. Try putting your access in the callback function passed to query().
$scope.cars = Cars.query(function() {
console.log($scope.cars);
console.log($scope.cars[0]._id);
});

TVRage consume service via AngularJS

i am trying to consume this webservice (http://services.tvrage.com/feeds/show_list.php) from TVRage using Angularjs.
I can 'connect' to the service (using firebug I see GET show_list.php STATUS 200 OK) but when i try to print any data from the response I get none.
This is the code that i use:
var TV_Episodes = angular.module('TV_Episodes', ['ngResource']);
TV_Episodes.controller('GetAllEpisodes', function($scope, $resource) {
var dataService = $resource('http://services.tvrage.com/feeds/show_list.php');
$scope.data = dataService.get();
console.log($scope.data());
});
any ideas on how I can just console.log the the response?
UPDATE 1:
After some more trying i found out that that i get the following error as a response from TVRAGE.
"XMLHttpRequest cannot load http://services.tvrage.com/feeds/show_list.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access."
therefor i tweaked my code so
var dataService = $resource('http://services.tvrage.com/feeds/show_list.php?key=xxxx',{},{headers: { 'Access-Control-Allow-Origin': '*' }});
but i still get the same error as before.
$resource.get() returns a promise, which means you are likely printing to the console prior to the data being retrieved. Instead use the appropriate callback function:
$scope.data = dataService.get(function() { console.log($scope.data); });
The get method is asyncronous. When it is called it returns immediately with a reference to an object (or array, if specified - but not a promise as indicated in MWay's answer). Then, later, that same reference is updated with the data that is returned from the server on success. Here's the relevant part from the documentation:
It is important to realize that invoking a $resource object method immediately returns an empty reference (object or array depending on isArray). Once the data is returned from the server the existing reference is populated with the actual data. This is a useful trick since usually the resource is assigned to a model which is then rendered by the view. Having an empty object results in no rendering, once the data arrives from the server then the object is populated with the data and the view automatically re-renders itself showing the new data. This means that in most cases one never has to write a callback function for the action methods.
As fast as the request might be, it won't resolve until the event loop comes around again. The resource is helpfully designed to free you up from having to worry about writing callbacks. If you need to though, the get method takes callback function parameters that will be invoked when the request resolves and the data is ready.
var TV_Episodes = angular.module('TV_Episodes', ['ngResource']);
TV_Episodes.controller('GetAllEpisodes', function($scope, $resource) {
var dataService = $resource('http://services.tvrage.com/feeds/show_list.php');
$scope.data = dataService.get(function () {
console.log($scope.data());
});
});
Or, you can access the promise used for processing the request by using *$promise", which is a property on empty instance object returned from get.

AngularJS Execute function after a Service request ends

I am using AngularJS Services in my application to retrieve data from the backend, and I would like to make a loading mask, so the loading mask will start just before sending the request. but how can I know when the request ends?
For example I defined my servive as:
angular.module('myServices', ['ngResource'])
.factory('Clients', function ($resource) {
return $resource('getclients');
})
.factory('ClientsDetails', function ($resource) {
return $resource('getclient/:cltId');
})
So I use them in my controller as:
$scope.list = Clients.query();
and
$scope.datails = ClientsDetails.get({
date:$scope.selectedId
});
So the question would be, how to know when the query and get requests ends?
Edit:
As a side note in this question I've been using using angularjs 1.0.7
In AngularJS 1.2 automatic unwrapping of promises is no longer supported unless you turn on a special feature for it (and no telling for how long that will be available).
So that means if you write a line like this:
$scope.someVariable = $http.get("some url");
When you try to use someVariable in your view code (for example, "{{ someVariable }}") it won't work anymore. Instead attach functions to the promise you get back from the get() function like dawuut showed and perform your scope assignment within the success function:
$http.get("some url").then(function successFunction(result) {
$scope.someVariable = result;
console.log(result);
});
I know you probably have your $http.get() wrapped inside of a service or factory of some sort, but you've probably been passing the promise you got from using $http out of the functions on that wrapper so this applies just the same there.
My old blog post on AngularJS promises is fairly popular, it's just not yet updated with the info that you can't do direct assignment of promises to $scope anymore and expect it to work well for you: http://johnmunsch.com/2013/07/17/angularjs-services-and-promises/
You can use promises to manage it, something like :
Clients.query().then(function (res) {
// Content loaded
console.log(res);
}, function (err) {
// Error
console.log(err);
});
Another way (much robust and 'best practice') is to make Angular intercepting your requests automatically by using interceptor (see doc here : http://docs.angularjs.org/api/ng.$http).
This can help too : Showing Spinner GIF during $http request in angular
As left in a comment by Pointy I solved my problem giving a second parameter to the get function as following:
$scope.datails = ClientsDetails.get({
date:$scope.selectedId
}, function(){
// do my stuff here
});

Breeze.Angular.Q 1.0.0 Setup

I followed the directions on BreezeJS Angular Q to "Install this module", however I receive an error on the fail() callback when making a dataservice call. When using Q.js, there was no problem.
error:
Object #<Object> has no method 'fail'
dataservice call:
dataservice.getAllEntities($scope.includeName, false, i, takeNum)
.then(querySucceeded)
.fail(queryFailed);
What could be up with my setup?
I think you need to pass the fail callback as the second parameter to then,
I see Q should have that .fail() shorthand, but it's probably better to just use the standard .then() notation:
From that page:
.then(successCallback, failCallback);
So your code should be like:
dataservice.getAllEntities($scope.includeName, false, i, takeNum)
.then(querySucceeded, queryFailed);
I'm not really sure why .fail doesn't exist though..

Testing for whether an object is an angularJS $resource

Simple (seeming) question - I'm trying to do a simple sanity check in my AngularJS controller to make sure that my $resource is actually instantiated as such. It's a largish app, but for example:
.factory('AccountSearchService_XHR', ["$resource", function($resource) {
var baseUrl = "http://localhost\\:8081/api/:version/accounts/:accountNumber";
return $resource(baseUrl,
{
version: "#version",
accountNumber: "#accountNumber"
},
{
get: {method: 'GET', isArray: false}
});
}]);
Then later, in controller:
$scope.accountObj.currentAccount = AccountSearchService_XHR.get({
version: "v1",
accountNumber: "1234"
},
function(result) {... etc etc});
The call to my API works fine, everything returns data like I expect - but I'd like to test to see if $scope.accountObj.currentAccount is a Resource before trying to make the .get call (notice the super important capital "R").
When I inspect the object $scope.accountObj.currentAccount in chrome debugger, it looks like:
Resource {accountHolderName: Object, socialSecurityNumer: null, birthDate: "05/14/1965", maritalStatus: ...}
Because of some complexity in my setup though, occasionally it gets overwritten as a normal object (typeof returns "object"), but inspecting it in debugger confirms it lost its Resource status.
So - does anyone know of a way to test whether it is a $resource? Almost like typeof $scope.accountObj.currentAccount returns "Resource"? Or perhaps a better best practices way to ensure that things are connecting up all proper and respectable-like?
All the SO articles I have seen when searching revolve around actual Jasmine testing.
Thanks in advance.
#tengen you need to have injected the type you want to check against, instead of $resource.
All resources are instances of the "class" "Resource", but that's a function that's defined inside of the factory method of the $resource service, so you have no outside visibility to use it with the instanceof operator.
However, you're wrapping that $resource creating with your own custom type, AccountSearchService_XHR, and that's what you need to make the check against.
You need AccountSearchService_XHR to be injected in your code and then perform myRef instanceof AccountSearchService_XHR and that will be === true.
Digging up an old question my intern just had. The simple solution is:
if ($scope.accountObj.currentAccount instanceof AccountSearchService_XHR)
return 'This is a AccountSearchService_XHR Resource';
else
return 'This is not a AccountSearchService_XHR Resource';
which with proper names (Users being a $resource) and real case scenario should lead you to write something like this:
if (!(this.user instanceof Users))
this.user = new Users(this.user);
this.user.$update();
Check it via instanceof yourVariable === "Resource". Because Resource is an object the type will always return as an Object, but if you check that it's an instance of the Resource "class" that should work just fine.

Resources