How to create a nested $resource - AngularJS - javascript

I'm trying to figure out how to create a nested $resource. I have come up with the following, which seems to work..ish, but seems awfully wrong. Hoping someone can point me in the right direction.
My data structure is:
allData = [{
id:1,
info:'someinfo',
foo :'foobar',
bar : {...},
baz : [{...}, {...}, {...}]
},
{id:2, ...},
{id:3, ...}
];
I would like each object in allData to be a $resource object. I also want each object in the baz array to be a $resource object as well.
What I have come up with is:
var InfoService = angular.module('InfoServices', ['ngResource']);
// The inner resource
InfoService.factory('Baz', ['$resource',
function($resource) {
var baz = $resource('/server/baz', {});
// custom baz methods
baz.prototype.getBaz = function() {};
return baz;
}]);
// Outer resource
InfoService.factory('Info', ['$resource',
function($resource) {
var info = $resource('/server/info', {});
// custom data methods
info.prototype.getInfoStats = function() {};
return info;
}]);
// Array of resources.
InfoService.factory('AllInfo', ['$resource','Info', 'Baz',
function($resource,Info,Baz) {
var resource = $resource('/server/allinfo', {},
{ query : {
method:'get',
isArray:true,
transformResponse:function(data) {
var allinfo = JSON.parse(data);
for (var i=0;i<allinfo.length;i++) {
allinfo[i] = new Info(allinfo[i]);
for (var j=0;j<allinfo[i].baz.length;j++) {
allinfo[i].baz[j] = new Baz(allinfo[i].baz[j]);
}
}
return allinfo;
}
});
return resource;
}]);
Like I said..seems awfully wrong, what's the Angular way to achieving the above?

InfoService.factory('resources', function($resource) {
return {
id: $resource(...),
info: $resource(...),
//...and so on...
}
})
//example usage
InfoService.controller('ctrl', function(resources) {
this.id = resources.id.query();
})
If you want to make everything a resource, this is the way to go. But ask yourself...is it really necessary to make every attribute a separate resource? What about grouping in a resource all attributes that are strictly related? I ask because I am not sure of what these data rapresent to you.

Related

Accessing the query variable from within callback

Take the following example:
getOptions() {
let options = {};
if (this.props.location.hasOwnProperty('query')) {
const query = this.props.location.query;
const queriesMap = {
'createdBy': 'createdBy',
'state': 'state',
'created_from': 'created_at[from]',
'created_to': 'created_at[to]'
};
Object.keys(query).map(function(key) {
if(queriesMap.hasOwnProperty(key)) {
options = Object.assign(options, { queriesMap[key]: query[key] });
}
});
}
return options;
}
I'm using the queriesMap object to map url parameters to build a new url to call an API. The problem is that query is undefined when I'm trying to access it from within the .map callback.
How do I access the query variable?
Looks like you are missing a [] around queriesMap[key]. So it should be options = Object.assign(options, { [queriesMap[key]]: query[key] });.
Also, you could just do options[queriesMap[key]] = query[key] rather than Object.assign

How to have multiple keys referencing one value in AngularJS

I have the following AngularJS value provider :
myApp.value('myValueProvider',
{
'k1': 'v1',
'k2': 'v2',
'k3': 'v2'
});
Where 'v2' is a complex Object so I don't want to duplicate every v2 values from k2 to k3.
So my goal is to obtain something like this:
myApp.value('myValueProvider',
{
'k1': 'v1',
'k2': 'v2',
'k3': myValueProvider.k2
});
Do you know if it's possible?
How about something like this:
// create the complex object that you want to assign to multiple properties
var complexObj = {
... your complex obj props ...
};
// create the provider object and assign the complex object reference to multiple properties
var valueProviderObj = {
k1: 'v1',
k2: complexObj,
k3: complexObj
};
// associate the provider object to the angular value by key name
myApp.value('myValueProvider', valueProviderObj);
You can change it in run stage.
var myApp = angular.module('myApp', []);
myApp.value('myValueProvider',
{
'k1': 'v1',
'k2': 'v2'
});
myApp.run(function(myValueProvider) {
myValueProvider.k3 = myValueProvider.k2;
});
myApp.controller('ctrl', function(myValueProvider) {
console.log('from controller', myValueProvider);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="ctrl"></div>

Use function to rewrite JSON object keys?

I have a program and want to change the object key names in a JSON file with a function. I have already created a function that changes the keys when it is displayed via Angular, but I want to create a function that allows me to change the object key names directly in the JSON file.
Here is a sample of my JSON file ( the actual array contains over 300 entries ):
[
{
"FIELD1":"key",
"FIELD2":"company",
"FIELD3":"team",
"FIELD4":"num_female_eng",
"FIELD5":"num_eng",
"FIELD6":"percent_female_eng",
"FIELD7":"last_updated",
"FIELD8":"Submit more data!",
"FIELD9":"https://github.com/triketora/women-in-software-eng"
},
{
"FIELD1":"all",
"FIELD2":"ALL",
"FIELD3":"N/A",
"FIELD4":"2798",
"FIELD5":"14810",
"FIELD6":"18.89",
"FIELD7":"11/18/2015",
"FIELD8":"",
"FIELD9":""
},
{
"FIELD1":"wellsfargo",
"FIELD2":"Wells Fargo",
"FIELD3":"N/A",
"FIELD4":"1296",
"FIELD5":"5407",
"FIELD6":"23.97",
"FIELD7":"7/22/2015",
"FIELD8":"",
"FIELD9":""
}
]
and what I have done thus far to change the key names:
(function() {
'use strict';
angular
.module("app.companies")
.controller('CompaniesCtrl', CompaniesCtrl);
CompaniesCtrl.$inject = ['$scope', 'CompanyFactory'];
function CompaniesCtrl($scope, CompanyFactory) {
$scope.work = "i work";
$scope.companies = CompanyFactory;
$scope.makeChart = function(company){
$scope.femaleDevs = parseInt(company.num_female_eng);
$scope.allDevs = parseInt(company.num_eng);
$scope.company = company.company;
$scope.maleDevs = $scope.allDevs - $scope.femaleDevs;
console.log($scope.maleDevs);
};
}
})();
Thank you for all of your help :) !
Maybe this should help you:
var fieldsmap = {
'FIELD1': 'key',
'FIELD2': 'company',
'FIELD3': 'team',
'FIELD4': 'num_female_eng',
'FIELD5': 'num_eng',
'FIELD6': 'percent_female_eng',
'FIELD7': 'last_updated',
'FIELD8': 'name2',
'FIELD9': 'name3'
};
function renameObjectKeys(obj) {
for (var key in fieldsmap) {
if (obj.hasOwnProperty(key) && fieldsmap.hasOwnProperty(key)) {
obj[fieldsmap[key]] = obj[key]; //copy the key into new key
delete(obj[key]); // delete old key
}
}
}
myArray.forEach(function(object) {
renameObjectKeys(object);
});

Angularjs : fitlering json properties to be send in a request

Is there anyway to tell angularjs ( $http service) not to send some properties into a Json object when doing a HTTP POST?
Let's say that i have an Object definition like this :
$scope.toBeSaved = { id : 1,
name: myname,
someAttributeTobeFiltered : 1233459,
}
Is There anyway to filter the someAttributeTobeFiltered not to be send during a $http.post(url,$scope.toBeSaved) call?
Thanks in advance
This will remove the given property on every request made via $http.
.config(['$httpProvider', function($httpProvider )
{
$httpProvider.defaults.transformRequest = [function(data)
{
if(typeof data === "object")
{
var toSend = angular.copy(data);
delete toSend.someAttributeTobeFiltered;
return toSend;
}
else{
return data;
}
}];
}]);
So using _.omit method you can do following:
$http.post(url, _.omit($scope.toBeSaved, ['someAttributeTobeFiltered', 'foo', 'bar']))

Trying to post object with parameters - angular js

I am trying to do a http get in angular like this:
$http
.get(some url, {
params: {
description: params.description,
from: params.from,
to: params.to
}
})
.success(function (data,status) {
$scope.info_show = data
});
here's the thing, the params object parameters are set based in user input, so if the user hasn't inputted anything for the from property (some input text fielt) it will be undefined.
my problem is that I can't just pass the params object, because it doesn't filter and if I pass undefined on even one of the properties then the web service by default will return everything, could someone show me a way of dynamically doing this?
You could use a function to filter the params object.
This one receives a list of params/properties you want to filter and the src object to filter from:
var filterParams = function(params, src) {
var result = {};
angular.forEach(params, function(p) {
if (angular.isDefined(src[p])) {
result[p] = src[p];
}
});
return result;
};
And then use it like this:
$http.get(some url, {
params: filterParams(['from', 'to', 'description'], params)
})
.success(function (data,status) {
$scope.info_show = data
});

Categories