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);
});
Related
I have a controller that that looks like this:
(function() {
angular
.module("main")
.controller("HomeCtrl",
["branchResource",
"adalAuthenticationService",
HomeCtrl]);
function HomeCtrl(branchResource, adalService){
var vm = this;
vm.copyrightDate = new Date();
vm.user = adalService.userInfo.userName;
// right here, can I insert the vm.user from above
// as a parameter to the resource's query?
branchResource.query(function (data) {
vm.branches = data;
});
}}());
The user is authenticated by the time they reach this point in the app. So, the user's info is available.
I have a backend API that takes a user's name and returns the names of branches that user is authorized to. I can paste the URL into my browser, along with a valid user name, and get expected results. I'm trying to use that API in my branchResource:
(function () {
"use strict";
angular
.module("common.services")
.factory("branchResource",
["$resource", branchResource]);
function branchResource($resource){
return $resource("/api/user/GetAllUserBranches?federatedUserName=:user")
}}());
My problem, though, is that I don't know how to pass the vm.user to the branchResource from the controller. Can someone point me in the right direction?
Create the $resource object with:
function branchResource($resource){
̶r̶e̶t̶u̶r̶n̶ ̶$̶r̶e̶s̶o̶u̶r̶c̶e̶(̶"̶/̶a̶p̶i̶/̶u̶s̶e̶r̶/̶G̶e̶t̶A̶l̶l̶U̶s̶e̶r̶B̶r̶a̶n̶c̶h̶e̶s̶?̶f̶e̶d̶e̶r̶a̶t̶e̶d̶U̶s̶e̶r̶N̶a̶m̶e̶=̶:̶u̶s̶e̶r̶"̶)̶ ̶
return $resource("/api/user/GetAllUserBranches")
}}
Call the $resource object with:
branchResource.query({"federatedUserName": vm.user}, function (data) {
vm.branches = data;
});
//OR
vm.branches = branchResource.query({"federatedUserName": vm.user});
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.
Each key value in the parameter object is first bound to url template if present and then any excess keys are appended to the url search query after the ?.
For more information, see AngularJS ngResource $resource API Reference.
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.
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)
}
})
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.
In my meanjs app created using meanjs generator and auto generated CRUD-module, for income below, I want to customize the promise returned by the get method so that I can call methods and do transformations on the retrieved data. So i attempt to change it in my controller:
// Find existing Income
$scope.findOne = function() {
Incomes.get({
incomeId: $stateParams.incomeId
}).then(function(income){
$scope.income = income;
$scope.incomeDollar= income*$scope.dollarRate;
});
This only gives me the error : undefined is not a function, and pointing on then.
What am i doing wrong here? How can I do transformations on the data retrieved from the get method above?
The pattern i am trying to use is in the end of the article here. I want to switch from the short version to the long so that i can do more stuff in my callback.
// LONG:
myModule.controller('HelloCtrl', function($scope, HelloWorld) {
HelloWorld.getMessages().then(function(messages) {
$scope.messages = messages;
});
});
To simplify this, the writer of the article place the promise returned by ‘getMessages’ on the scope:
// SHORTER:
myModule.controller('HelloCtrl', function($scope, HelloWorld) {
$scope.messages = HelloWorld.getMessages();
});
The promise object can be accessed using $promise. From the doc
The Resource instances and collection 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...
So, your code should look like:
// Find existing Income
$scope.findOne = function() {
Incomes.get({
incomeId: $stateParams.incomeId
}).$promise.then(function(income){
$scope.income = income;
$scope.incomeDollar= income*$scope.dollarRate;
});