I have the following code in a controller:
$scope.chart = $resource('/api/chart/01234').get();
// { name: 'Foobar', id: '01234' }
$scope.send = function() {
$scope.chart.$save();
}
But after the user triggers send(), the only properties remaining in $scope.chart are those from $resource (e.g. $promise, $save, toJSON, etc…), the others are gone (no name or id).
I still don't understand why the instance's $save() wipes the instance, but using the class' save() works:
var Chart = $resource('/api/chart/01234');
$scope.chart = Chart.get();
$scope.send = function() {
Chart.save({}, $scope.chart);
}
Could be this:
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.
From angular docs under the Returns section.
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 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.
I'm relatively new to Angular and trying to correct some functionality someone left us with. I have a service that retrieves JSON from another service, and then I'd like to use that JSON within the original service. I have it working when accessing a single value from the JSON being returned, but I'd like to store the entire object so I can easily reference it throughout.
For instance, this works, and sets the value of title (title: cfgTitle) to the TITLE value coming back from the JSON:
.service("rtmModel", function($q, dataGetter, $http) {
this.getModel = function() {
var cfgProm = dataGetter.getData()
var cfgTitle = cfgProm.then(function(response) {
return response.data.record1.TITLE;
});
return {
title: cfgTitle,
desc:
...
However, if I return anything else from the "then" function I can't get stuff to show up. For instance, this does not work (appears to be passing undefined for the title param):
.service("rtmModel", function($q, dataGetter, $http) {
this.getModel = function() {
var cfgProm = dataGetter.getData()
var cfgTitle = cfgProm.then(function(response) {
return response.data.record1;
});
return {
title: cfgTitle.TITLE,
desc:
...
If I simply return "response" from the "then" function and do:
return {
title: cfgTitle.
then I get the entire JSON string passed into Title (and I understand why), but attempting to drill down (i.e. title: cfgTitle.data, or title: cfgTitle.data.record1) just results in undefined values.
I've tried various methods of storing the returning JSON data, but can't find the secret sauce that will allow me to store the JSON object, and then use it to pass multiple parameters down below (i.e. I want to pass a value into title, another into desc, and so forth).
Any pointers would be appreciated.
You can't return values/objects from the anonymous function callbacks that you pass to the .then method of a promise. Those callbacks are invoked internally by the promise library and the return value is ignored. You have two options. Refer a reference to a new object from getModel and copy the data returns from getData into it. Or, return a new promise from your getModel method, and resolve that promise when the promise returned from getData is resolved.
The later option (returning a promise to the caller) will look something like this (won't compile):
.service("rtmModel", function($q, dataGetter, $http) {
this.getModel = function() {
var defer = $q.defer();
dataGetter.getData().then(function(response) {
defer.resolve(response.data.record1);
});
return defer.promise;
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;
});
}