How to remove $promise and $resolved from json object - javascript

I'm using $resource in angular to get json object and its structure is defined below
[
{
"id": 0,
"name": "Type1"
},
{
"id": 1,
"name": "Type 2"
}
]
after fetching the data .. console.log(jsonObject) gives me
[Resource, Resource, $promise: Object, $resolved: true]
How can I remove $promise & $resolved from the resulting object ?
I tried angular.fromJson(json) but still I see that these objects still exist.

I'm looking for the same answer, but at this moment I know only this ugly hack:
To write a func like this:
function cleanResponse(resp) {
return JSON.parse(angular.toJson(resp));
}
and call it in every single query (ugly, yep):
function getSmt() {
Resource.get({}, function (data) {
$scope.some = cleanResponse(data);
}, function (responce) {
//handle error
})
}
I'll be happy if someone would teach me how to do it correctly

Example from my project
Diary.getSharedWithMe(function(data) {
delete data.$promise;
delete data.$resolved;
_self.sharedDiariesWithMe = data;
}, function(error) {
console.log(error)
});

From this answer, it looks that yourResource.toJSON() is readily available.

Right, I've faced the same problem several times and always ended up using $http instead of $resource, however, today I decided to try and deal with this issue. I hope somebody will find this useful one day as well.
So, after you receive your object with $promise inside of it, what you do is just use angular.copy(data), like so:
someService.getSomething($scope.someId).$promise.then(function (data) {
if (data) {
$scope.dataWithoutPromise = angular.copy(data);
}
});
After that, you will see that your dataWithoutPromise just contains the objects that you need, and $promise and $resolved are gone.

I'm facing the same issue. In fact, you simply have to use the same version of angular and angular-resource and it will work like a charm.
Hope it helps !

Short answer : angular.fromJson(angular.toJson(resp));
This will remove all "angular specific" functions etc and will return you a clean data object.

Are you using isArray or .query() with your $resource object?
From the $resource docs: isArray – {boolean=} – If true then the returned object for this action is an array.
UPDATE:
If you are using $resource correctly, some options you have are:
1) Have the backend return the data contained within an object, eg. { data: [] } rather than just an array.
2) If that is not possible, use the callback from the $resource.query(), eg.
MyResource.query({ myParams: 'something'}, function(result) {
// Do something with the plain result
});

I did this quick reusable method for angular.toJson (Properties with leading $$ will be stripped):
yourApp.factory('Service', ['$resource', function ($resource) {
return $resource('your/rest/api/path');
}]);
yourApp.factory('commonServices', function () {
return {
toJson : function(response){
return JSON.parse(angular.toJson(response));
//*or*
//return angular.toJson(response);
}
});
And then something like this in your controller:
yourApp.controller('Controller', ['$scope', 'Service','commonServices',
function ($scope, Service, commonServices) {
Service.get().then(function (data) {
$scope.myData = commonServices.toJson(data);
});
});
the more simple way is to add angular.toJson in the controller
yourApp.controller('Controller', ['$scope', 'Service',
function ($scope, Service, commonServices) {
Service.get().then(function (data) {
$scope.myData = angular.toJson(data);
});
});

Please simply do this:
jsonObject.$promise = undefined;
jsonObject.$resolved = undefined;
$promise and $resolved will not be removed but you will be able to do what you want.

Try to code something like this in your service:
yourApp.factory('Service', ['$resource', function ($resource) {
return $resource('your/rest/api/path');
}]);
And then something like this in your controller:
yourApp.controller('Controller', ['$scope', 'Service', function ($scope, Service) {
Service.get().then(function (data) {
$scope.myData = data;
});
});

Related

AngularJS: Service call API and return JSON

I need to pass a value from an input field on the view using a service. The service should call my WebAPI2 and then receives an valid JSON as a response.
However, I am either getting an promise object, which I cannot resolve (even with ".then()"), or if I'm using an factory it won't compile as it seems to not implement the $get method.
The JSON Object I'm returning is also valid.
View :
<div class="input" ng-controller="InputController as ctrl">
<input ng-model="inputdata" /> {{inputdata}}
<button ng-click="ctrl.gibDaten(inputdata)">Senden</button>
{{cooledaten}}
</div>
Controller :
module GoogleMapsApp {
myApp.myAppModule.controller("InputController",
["$scope", "mapsServiceCustom",
function ($scope, mapsServiceCustom) {
$scope.lEingabedaten = $scope.inputdata;
this.gibDaten = function () {
$scope.cooledaten = mapsServiceCustom.gibDaten().then();
console.log($scope.cooledaten);
}
}]);
}
Service:
module GoogleMapsApp {
myApp.myAppModule.service("mapsServiceCustom",
["$http",
function ($http) {
this.gibDaten = function (lEingabe) {
console.log(lEingabe);
console.log($http.get("api/getDistanceData/" + lEingabe + "/Cologne")
.then(function(data) {
return data;
Controller:}));
return $http.get("api/getDistanceData/" + lEingabe + "/Cologne")
.then(function (data) {
return data;
});
//return $http.get("api/getDistanceData/" + lEingabedaten1 + "/Cologne");
}
}
]);
}
Console log:
Object { $$state: Object }maps.serviceCustom.js:14:17
Object { $$state: Object }InputController.js:8:17
If I check the $$state:Object it contains exactly the desired data.
Using a factory leads me to the following error:
https://docs.angularjs.org/error/$injector/undef?p0=mapsServiceCustom
So what am I doing wrong? How would I implement my intend?
You need to pass a function to then part...
So just put then function in your controller and set returning response to your variable...
myApp.myAppModule.controller("InputController",
["$scope", "mapsServiceCustom",
function ($scope, mapsServiceCustom) {
$scope.lEingabedaten = $scope.inputdata;
this.gibDaten = function () {
mapsServiceCustom.gibDaten().then(function(response){
// set response to your variable
$scope.cooledaten = response;
});
}
}]);
You have not implemented the service properly. please go through the following link (Angularjs official documentation)
https://docs.angularjs.org/guide/services
You need to expose your API by returning it an js object.(Same thing is shown in your error link. please refer to that as well)
module GoogleMapsApp {
myApp.myAppModule.service("mapsServiceCustom",
["$http", function ($http) {
this.gibDaten = function (lEingabe) {
console.log(lEingabe);
console.log($http.get("api/getDistanceData/" + lEingabe + "/Cologne")
.then(function(data) {
return data;
}
}
return { gibDaten: this.gibDaten};
}]);
}
Here You can learn more on $get
method https://docs.angularjs.org/guide/providers

AngularJS - Am I missing something in this Factory injection?

I'm using the $cacheFactory to save some data in my cache and everything was working very good until today that I've decided to separate my cacheFactory into a single class called MyFactory.js. Now I'm getting the error:
TypeError: tableCacheFactory is not a function
Because it's taking the injection as a simple method or something, does anybody know if I'm missing something here?
main.js
angular.module('main-component',
['my-component',
'my-cache-factory'
]);
MyFactory.js
angular.module('my-cache-factory', [])
.factory('tableCacheFactory', [
'$cacheFactory', function ($cacheFactory) {
return $cacheFactory('my-cache');
}
]);
MyService.js
angular.module('my-component', [])
.factory('my-component-service',
['$rootScope',
'$http',
'$q',
'tableCacheFactory',
function ($rootScope, $http, $q, tableCacheFactory) {
function getMyData (prodNro) {
var deferred = $q.defer();
var promise = deferred.promise;
var dataCache = tableCacheFactory.get('tablecache');
if (!dataCache) {
dataCache = tableCacheFactory('tablecache'); // TypeError: tableCacheFactory is not a function
}
var summaryFromCache = dataCache.get('tablecache' + prodNro);
if (summaryFromCache) {
deferred.resolve(summaryFromCache);
} else {
$http({
method: ...
data : ...
url: ...
}).success( function (data, status, headers, config) {
var objectResult = {
"data": data,
"status": status,
"headers": headers,
"config": config
}
if (data.response) {
// Save to cache
dataCache.put('tablecache'+prodNro, objectResult);
}
deferred.resolve(objectResult);
}).error(function (data, status, headers, config) {
...
});
}
return promise;
}
You seem to have some misconception about how the $cacheFactory works.
In var dataCache = tableCacheFactory.get('tablecache'); you are using it like it was a initialized Cache object containing another Cache object.
On the other hand dataCache = tableCacheFactory('tablecache'); uses it like it was the $cacheFactory itself.
And both of them try to access record 'tablecache' in something that I think should already be the tableCache itself.
The error is exactly what it says it is. As per the docs, calling $cacheFactory('my-cache'); does not return a function to create more caches.
It returns a $cacheFactory.Cache object which has methods like put(key, value) and get(key). Use those instead.
I'd change the whole structure of the caching (note that the name of the factory is changed):
.factory('tableCache', [
'$cacheFactory', function ($cacheFactory) {
//Return what the name of the factory implies
return $cacheFactory('tablecache');
}
]);
And then use that without needing to do more weird 'tablecache' namespacing
function getMyData (prodNro) {
...
var summaryFromCache = tableCache.get(prodNro);
...
tableCache.put(prodNro, objectResult);
}
The tableCacheFactory was wrapped inside my-cache-factory module. So you need to inject the module first into your my-component module before using it. So it should be like this:
angular.module('my-component', ['my-cache-factory'])
you defined your cache factory in the module my-cache-factory, but then never injected that module to your main component-service module. Do angular.module('my-component', ['my-cache-factory']) instead.

Trouble getting json from API with angular

Trying to pull in some data using angular and an API. Obviously I'm quite new to this.
My custom service:
readIp.service('ip', ['$resource', function($resource){
this.getIP = function(ip) {
var ipData = $resource("http://www.telize.com/jsonip?callback=getip", {
callback : "JSON_CALLBACK"
}, {
get : {
method: "JSONP"
}
});
return ipData.get({ getip: ip });
}
}]);
From my controller:
$scope.getIP = ip.getIP($scope.getip);
HTML:
<strong>Your IP is:</strong> {{ getIP.ip }}
I'm getting an error currently:
Uncaught ReferenceError: getip is not defined
as the API shows up as: getip({"ip":"###.###.##.##"}); from the source.
Your service isn't properly defined. It should return an object that contains your getIp method. try something along the lines of :
readIp.factory('ip', ['$resource', function($resource){
return {
getIP: function(ip) {
// your code goes here
}
}
}]);
try this in place of above code. Hope you have already added ngResource module.
readIp.factory('ip',['$resource',function($resource){
return $resource('http://www.telize.com/jsonip?callback=getip', {}, {
query: {method:'GET', params:{}}
});
}])

Using $http in Angular Service - Cannot read property 'post' of undefined

I'm trying to learn how to use Angular right, by having all my business logic in services.
When I do a post request in a service, I get the following error:
Cannot read property 'post' of undefined
Here is some code:
UrlApp.controller('UrlFormCtrl', UrlFormCtrl);
UrlApp.factory('addUrlService', addUrlService);
function UrlFormCtrl($scope, $http) {
console.log('Url Form Controller Initialized');
$scope.addUrl = addUrlService.bind(null, $http);
}
function addUrlService($scope, $http){
console.log('initializing addUrlService');
return $http.post('urls/create', {'test':'test'}).then(function(response){
return response.data;
});
}
I'm just getting the hang of Angular, so I'm not entirely sure what I'm doing wrong. See any problems?
Firstly, you don't need to inject $scope in your service.
Secondly, you don't need to inject $http service in your controller.
Thirdly, you need to inject the service in your controller.
Finally, addUrlService service is returning a promise meaning it will make a request when service is instantiated. You may want to return a function instead or an object containing several functions.
So I would change your code to:
UrlApp.controller('UrlFormCtrl', UrlFormCtrl);
UrlApp.factory('AddUrlService', AddUrlService);
function UrlFormCtrl($scope, AddUrlService) {
$scope.addUrl = AddUrlService.addUrl;
}
function AddUrlService($http) {
function addUrl() {
return $http.post('urls/create', {
'test': 'test'
}).then(function (response) {
return response.data;
});
}
return {
addUrl: addUrl
};
}
Can you try like this
UrlApp.controller('UrlFormCtrl', UrlFormCtrl);
UrlApp.factory('addUrlService', addUrlService);
function UrlFormCtrl($scope,addUrlService) {
console.log('Url Form Controller Initialized');
$scope.addUrl = addUrlService;
}
function addUrlService($http){
console.log('initializing addUrlService');
return $http.post('urls/create', {'test':'test'}).then(function(response){
return response.data;
});
}

Avoid saving returned data to ngResource

I have an ngResource object like this:
[...].factory('Event', ['$resource', function ($resource) {
return $resource('/events/:id', {id: '#id'}, {
resume: {url: '/events/:id/resume'},
signUpload: {url: '/events/:id/sign-upload'},
});
}]);
But when I call myModel.$resume(); or myModel.$signUpload() the returned data gets automatically saved to my model. However, the returned data is not my model attributes, but actually another completely different return.
I need to avoid auto-saving the returned data from the server. Is there anything out-of-the-box to do that? I couldn't find it here: https://docs.angularjs.org/api/ngResource/service/$resource
Thanks
For this case you can try to not use resource, but create service.
app.service('eventService', ['$http, $q', function ($http, $q) {
this.signUpload = function(eventId) {
var defer = $q.defer();
$http.get('/events/' + eventId + '/sign-upload')
.then(function(result) {
defer.resolve(result.data);
})
.catch(function(err) {
defer.reject(new Error(err));
});
return defer.promise;
}
// same for other function
}]);
Inject this service in controller, and just do eventService.signUpload(eventId);

Categories

Resources