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.
Related
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);
});
I have a service defined which do the db related queries/updates. I have defined the controller which does the data parsing for the angular elements by getting the objects from the service. I would like to keep each scope different
How can I pass the data from service to controller using ngResource.
Sample Service:
app.factory("ioHomeService", ["$rootScope","$resource", function($rootScope,$resource) {
var svc = {};
var home = $resource('/home/getAll');
var dbData= home.get();
svc.getRooms = function() {
return dbData;
};
return svc;
}]);
Sample Controller:
app.controller("homeCtrl",["$scope","$mdDialog","ioHomeService",function($scope,$mdDialog,ioHome){
$scope.dbData = ioHome.getRooms();
//Here UI specific objects/data is derived from dbData
}]);
After the DB is queried and the results are avialble the dbData in service is reflecting the data from DB, but the Controller cannot get that data
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.
From https://docs.angularjs.org/api/ngResource/service/$resource
Since the 'ioHome.getRooms();' is being called before the $resource has returned the data you are getting dbData as an empty reference
app.factory("ioHomeService", ["$rootScope","$resource", function($rootScope,$resource) {
var svc = {
dbData : {}
};
var home = $resource('/home/getAll');
var svc.dbData.rooms = home.get();
return svc;
}]);
Controller
app.controller("homeCtrl",["$scope","$mdDialog","ioHomeService",function($scope,$mdDialog,ioHome){
$scope.dbData = ioHome.dbData;
//You can access the rooms data using $scope.dbData.roooms
//Here UI specific objects/data is derived from dbData
}]);
You would have to return the service object , like so :
app.factory("ioHomeService", ["$rootScope","$resource", function($rootScope,$resource) {
var svc = {};
var home = $resource('/home/getAll');
var dbData= home.get();
svc.getRooms = function() {
return dbData;
};
return svc; //here
}]);
Currently the getRooms method is not visible to your controller.
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.
This is my task: Get search selections from server when route to a search page or it child pages (eg: #/search/option1). The problem is how to share the selections to all search relative pages and don't request server twice and don't expose selections to root scope?
I don't know weather I describe clearly, not good at it. Thanks for your reading. Appreciate any tip, any.
You could get the result from the server and then reuse the result throughout you application.
Create a factory (or service) that retrieves and stores the values from the server:
app.factory('DataService', function($http) {
var values;
var requestValues = function() {
$http.get("/api/getValues").then(
function(results){
values = results;
});
};
var getValues = function() {
return values;
};
return {
requestValues : requestValues, // this will make a http request and store the result
getValues: getValues // this will call the stored result (without making a http request)
}
});
Now you have two functions in your factory.
requestValues() to make the http request and save the result locally
getValues() to get the locally saved values without making a http request.
Once requestValues() has been called, you should be able to call getValues() from anywhere to get the values without making a new http request.
myApp.controller('MyController', function ($scope, DataService) {
var init = function (){
DataService.requestValues(); // this will make the http request and store the result
$scope.items = DataService.getValues(); // this will get the result
};
var justGetValues = function(){
$scope.items = DataService.getValues(); // this will get the result (without making a http request)
};
});
Now you simply have to call DataService.getValues() whenever you need the values. (You might want to wrap these in a promise. I have refrained from doing this due to simplicity)
I have a resource factory with a POST method called update:
PnrApp.factory('Feed', function ($resource, $cacheFactory, $q, $rootScope) {
var Feed = $resource('api/feeds/:post', { post: 'post' }, {
get: { method:'GET' },
update: { method: 'POST' }
});
return Feed;
});
When I call the method it POSTs the data to the server as expected:
$rootScope.toggleStar = function (post, feedname) {
var updated = Feed.update(post);
this.child.StarId = updated.StarId;
}
And the server returns the correct values (notice the StarId in this json):
{"Name":"13 Ways to Act Like A Business Owner","ItemDate":"June 6, 2013","Url":"/post/13-Ways-to-Act-Like-A-Business-Owner-Stop-Acting-Like-an-Advisor-All-the-Time-(6-min-03-sec).aspx","StarImg":"bulletstar-on.png","StarId":1324,"StarDate":"0001-01-01T00:00:00","FeedCount":0,"FeedId":19,"SourceIcon":null,"IsBroken":false,"ItemId":"01"}
However, if you look at var updated's return value for StarId, notice how it's "0":
Can someone explain why this is, and how I can get at the return values in this situation?
Your var updated = Feed.update(post); makes an async call to the server and returns immedaitly and the updated object gets updated as soon as the server returns the data. So I guess you try to access the updated.StarId too early. From the angular doc:
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 ththeat in most case one never has to write a callback function for the action methods.
Try something like this:
$rootScope.toggleStar = function (post, feedname) {
var updated = Feed.update(post, function(f) {
this.child.StarId = f.StarId;
});
}