Not able to access property of an object - angularjs

I'm using $resource for making restful request to the server.
My code is
service.js
.factory('userServ',function($resource){
return $resource('url/:id',{id:'#id'},{
me: 'GET',isArray:false,url:'url2'}
});
})
I'm using this service in the controller like this
$scope.userDetails = userService.me();
console.log($scope.userDetails) // gives all the details of the user
console.log($scope.userDetails.username) // gives undefined. But username is there in the object
So how can I access that from the object

Your resource object returns a promise. Read more about it here: https://docs.angularjs.org/api/ngResource/service/$resource
var myResource = $resource('url/:id',{id:'#id'},{
me: 'GET',isArray:false,url:'url2'}
});
In order to get the data out of it you need to call the methods of the promise itself. They are GET, PUT and SAVE.
But here you only have a GET mentioned there.
So if you resolve your promise by calling
var myResult = [];
myResource.then(function(data){
myresult = date;
});
Now, 'myResult' here will have your returned data.
It can also be called like this ():
.get({userId:123})
.$promise.then(function(user) {
$scope.user = user;
});
Again I would recommend reading the angular docs to get a better understanding.

In your aprroach, promise is not resolved. So you are not able to naccess data.
Here,
$scope.userDetails = userService.me();
Promise is not resolved. when you expand your Object you will see resolved:false. Although you will be able to see data inside $scope.userDetails you needed.
So, first you need to wait till promise is resolved.For this you can use .then method.
var CallApi = userService.me().$promise; //Promise yet to be Resolved
CallApi.then(function (res)){ //Promise resolved here
$scope.userDetails = res;
console.log($scope.userDetails)
console.log($scope.userDetails.username)
}
})

Related

$resource object empty after get request

I want to save JSON-Data from my Rest-API in a $scope variable for further usage.
The problem is when the Code is executed, i see in Firebug that i've got the JSON Data sucessfully, but the problem is, that i cant save it in my Scope variable and i dont know why.
My app.js
var app = angular.module('shop', ['ngRoute','ngResource'])
.factory('Customerservice', function ($resource) {
return $resource('http://localhost:8080/Shop/:customer',{customer: "#customer"});
})
.config(function ($routeProvider, $locationProvider) {
$routeProvider.when('/name/:ID', {
templateUrl : "Customer/customers.html",
controller : 'customerController'
});
})
.controller('customerController', function ($scope,Customerservice) {
$scope.customerinfo = Customerservice.get({customer: "Mark"});
alert($scope.customerinfo);
});
Like i said, i've got the JSON-Data but the Problem is in my Controller "customerController". I just put the alert function in my Code to see whats in my $scope.customerinfo. And well the Content of customerinfo is just object: Object.
I noticed something strange while debbuging with Firebug. It looks like that the alert is executed before the get request. This would explain why there is no data in my $scope variable. Can anyone help me here.
Use $promise property
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.
$scope.customerinfo = CustomerService.get({customer: "Mark"});
console.log($scope.customerinfo); //Empty object
However, the $resource service also attaches a $promise property that can be used to delay code execution until the data has arrived from the server:
$scope.customerinfo = CustomerService.get({customer: "Mark"});
console.log($scope.customerinfo); //Empty object
//USE $promise
$scope.customerinfo.$promise
.then(function(info) {
console.log($scope.customerinfo); //Fulfilled object
return info;
}).catch(function(errorResponse) {
console.log(errorResponse.status);
throw errorResponse;
});
The Resource instances and collections have these additional properties:
$promise: the promise of the original server interaction that created this instance or collection.
On success, the promise is resolved with the same resource instance or collection object, updated with data from server. This makes it easy to use in resolve section of $routeProvider.when() to defer view rendering until the resource(s) are loaded.
On failure, the promise is rejected with the http response object, without the resource property.
— AngularJS ngResource $resource API Reference
$resource is async api so you can't get value from direct return of function call, its contains a variable $promise which will return promise so you need to call then function of it
Try this
UserService.get({customer: "Mark"}).$promise.then(function(data) {
$scope.customerinfo = data;
alert($scope.customerinfo);
});

how to return a value from a ajax promise

I have a method in my angular 1.5 controller, as shown below but I wanted to refactor the ajax call into the factory itself but I'm having problems with promises.. I'm trying to get to a point where in my controller I can just call the method like I've shown below. Is this possible? I'm trying to avoid having the ...success(function(...) in the controller code.
Any help much appreciated.
Trying to move to
vm.member = someFactory.getMember(vm.id);
Existing working controller code
vm.myMethod = myMethod;
...
function myMethod() {
someFactory.getMember(vm.id).success(function(response) {
vm.member = response;
});
}
When I move the getMethod line into the factory the response is populated obviously but as soon as I come back to the controller, even with the return value from the factory being the response the result is undefined. I know this is because of promises but is there a design pattern I'm missing or a clean way of doing this. Using my currently approach my controller is littered with .success(function()...)
Many thanks!
The procedure is called promise unwrapping.
Besides the fact that success is deprecated and should be replaced with then,
someFactory.getMember(vm.id).then(function(response) {
var data = res.data;
...
});
it is totally ok to have this in controller.
The alternative to this pattern is to return self-filling object (something that ngResource $resource does):
function getMember(...) {
var data = {};
$http(...).then(function (response) {
// considering that response data is JSON object,
// it can replace existing data object
angular.copy(data, response.data);
});
return data;
}
In this case controller can get a reference to the object instantly, and the bindings of object properties {{ vm.member.someProperty }} will be updated in view on response.
The pattern is limited to objects (and arrays), scalar values should be wrapped with objects.

how to get data from factories to services in restapi

Here coupon is the my ng-model passing parameter from controllers. i getting the response data. i dont know how to get the this response from factory to services.
please help me..
var factmodule=angular.module("FactModule",["ngResource"]);
factmodule.factory("CouponFactory",function($resource){
var couponinfo;
var coupondata
return{
getcoupon:function(coupon){
var user=$resource("http://demo.foodzard.in/api/promocode?code="+coupon.offer);
user.get(function(data){
couponvalue=data
console.log(data);
return couponvalue;
})
}
}
})
Services code
var servctrl=angular.module("ServModule",["FactModule"]);
servctrl.service("CouponService",function(CouponFactory){
this.checkdata=function(coupon){
CouponFactory.getcoupon(coupon)
}
})
controllers code
// getting coupon code from ng-model in the text box
mainCtrl.controller("OrderController",function($scope,CouponService){
$scope.validate=function($scope.coupon){
CouponService.checkdata($scope.coupon)
}
});
If factmodule is in a separate module from servctrl then you need to inject the factmodule into the servctrl on creation of the angular module
e.g.
var servctl = angular.module('servctl', [
'factmodule']);
})();
what I would be doing is
app.factory("CouponFactory",function($resource){...
and
app.service("CouponService",function(CouponFactory){
Then they are in the same module and would be reachable
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.1
Since the return couponvalue; statement occurs in a function that the $q service invokes in the future, the factory function which executes immediately does not return any data.
Instead return the empty user reference and use its $promise property to retrieve the data.
var factmodule=angular.module("FactModule",["ngResource"]);
factmodule.factory("CouponFactory",function($resource){
var couponinfo;
var coupondata
return {
getcoupon:function(coupon){
var user=$resource("http://demo.foodzard.in/api/promocode?code="+coupon.offer);
//return object reference
return user.get();
}
}
})
Use $promise property to retrieve data from the $q service.
var servctrl=angular.module("ServModule",["FactModule"]);
servctrl.service("CouponService",function(CouponFactory){
this.checkdata=function(coupon){
return resourceObject = CouponFactory.getcoupon(coupon);
//retrieve future data
resourceObject.$promise.then( onFullfilled(data) {
var couponvalue=data;
console.log(data);
});
});
});
The .then method of a promise takes a function as an argument. The $q service stores that function and invokes it in the future when the XHR completes.

AngularJS : Service data binding

I am trying to call a service in angular.js through a controller on load and return a promise. I then expect the promise to be fulfilled and for the DOM to be updated. This is not what happens. To be clear, I am not getting an error. The code is as follows.
app.controller('TutorialController', function ($scope, tutorialService) {
init();
function init() {
$scope.tutorials = tutorialService.getTutorials();
}
});
<div data-ng-repeat="tutorial in tutorials | orderBy:'title'">
<div>{{tutorial.tutorialId}}+' - '+{{tutorial.title + ' - ' + tutorial.description}}</div>
</div>
var url = "http://localhost:8080/tutorial-service/tutorials";
app.service('tutorialService', function ($http, $q) {
this.getTutorials = function () {
var list;
var deffered = $q.defer();
$http({
url:url,
method:'GET'
})
.then(function(data){
list = data.data;
deffered.resolve(list);
console.log(list[0]);
console.log(list[1]);
console.log(list[2]);
});
return deffered.promise;
};
});
Inside of the ".then()" function in the service, I log the results and I am getting what I expected there, it just never updates the DOM. Any and all help would be appreciated.
getTutorials returns promise by itself. So you have to do then() again.
tutorialService.getTutorials().then(function(data){
$scope.tutorials = data;
});
Before that, $http returns a promise with success() and error().
Although you can also use then as well
Since the returned value of calling the $http function is a promise,
you can also use the then method to register callbacks, and these
callbacks will receive a single argument – an object representing the
response.
So you are correct with that.
What is your data coming from the http call look like? Your code works - I created a version of it here http://jsfiddle.net/Cq5sm/ using $timeout.
So if your list looks like:
[{ tutorialId: '1',
title : 'the title',
description: 'the description'
}]
it should work
In newer Angular versions (I think v 1.2 RC3+) you have to configure angular to get the unwrap feature working (DEMO):
var app = angular.module('myapp', []).config(function ($parseProvider) {
$parseProvider.unwrapPromises(true);
});
This allows you to directly assign the promise to the ng-repeat collection.
$scope.tutorials = tutorialService.getTutorials();
Beside that I personally prefer to do the wrapping manually:
tutorialService.getTutorials().then(function(tutorials){
$scope.tutorials = tutorials;
});
I don't know the exact reason why they removed that feature from the default config but it looks like the angular developers prefer the second option too.

AngularJS: 'Collector' service returns promise; how to resolve within function to still pass value?

I've written a service Collector to store my models, which interfaces with localStorage and my server. I have a function Collector.retrieveModel(uuid) which retrieves a model from the collector, first checking localStorage to see if it is already extant, otherwise requesting it from my server.
Here's what it looks like:
var retrieveModel = function(uuid) {
var deferred = $q.defer();
var promise = deferred.promise;
if (typeof uuid === 'undefined') {
console.log("retrieveModel called without param");
deferred.resolve( collector );
}
if ( collector[uuid] = localStorage.getItem(uuid) ) {
//object was in local storage, return the data
**Problem is somewhere around here**
deferred.resolve( collector[uuid] );
} else {
//doesn't exist in collector, request it
//remoteModel is a wrapper function, which itself returns a promise, which is resolved upon a successful call using $resource
remoteModel(uuid).then(function (val) {
deferred.resolve(val);
});
}
return promise;
};
As it currently exists, it the model was not present in localStorage (and remoteModel is called) the promise is returned, and fulfilled once the model is retrieved from the server. subsequently, the relevant $scopes are updated. This works as expected.
However, when the model is present in localStorage, then the deferred is resolved, but before the function returns a promise. Thus, the resolved value is never propagated.
What can I do to consistently return a promise, but not fulfill it prematurely? I don't want to use $timeout.
I think you're very close; on mobile so I can't test right away but I think if you resolved your promise inside a .then() callback you'd get the desired result. Something to the effect of:
deferred.promise.then(function () {
deferred.resolve( collector[uuid] );
})
The idea being you want to wait until the function returns the promise, invokes the then() in which you resolve your local storage response.

Resources