Best approach to manage related objects in angular? - angularjs

Let's say I have two json objects, one of users and one of accounts, something like:
users = [
{id: 1, account_id: 1},
{id: 2, account_id: 2},
{id: 3, account_id: 1}
]
accounts = [
{id: 1, name: "administrator"},
{id: 2, name: "moderator"}
]
So I have to loop accross all the users array, and for each of them get the account information. Which is the best way to manage those relationships for accessing them in the markup? I found the following solutions:
Approach 1: Make a repeat of only one element, so that it's just to filter the elements and to make it available in that part of the markup
<div ng-repeat="user in users">
<div ng-repeat="account in getAccountFromId(user.account_id)">
<!-- now account is available in all this scope to access user.account.name -->
</div>
</div>
Approach 2: Change the way the information is returned from the backend, bringing a json of each user where each json is returned with the account information. But that will repeat a lot of informacion in each json object. Also this implies changing the backend because of angular.
<div ng-repeat="user in users">
<!-- with this approach I can access here user.account.name -->
</div>
Could someone tell me if those approachs are correct? Is there a better way to manage the object relationships in angular?
Thanks a lot.

If you really don't like the thought of changing the shape of the data coming from the server, another option is to just map the users to accounts in javascript.
app.controller("MyController", function($scope) {
// Pretend that 'users' and 'accounts' here came from an xhr request
var users = [
{id: 1, account_id: 1},
{id: 2, account_id: 2},
{id: 3, account_id: 1}
]
var accounts = [
{id: 1, name: "administrator"},
{id: 2, name: "moderator"}
]
// Map accounts to users
for(var i=0; i<users.length; i++) {
for(var j=0; j<accounts.length; j++) {
if (accounts[j].id === users[i].account_id) {
users[i].account = accounts[j];
}
}
}
});

I faced the same problem and decided it was not the front-end job to perform data mapping.
So instead of returning on account_id like:
users = [
{id: 1, account_id: 1},
{id: 2, account_id: 2},
{id: 3, account_id: 1}
]
I extended the model with "account_name" (or whatever the equivalent for me)
Hence the suggested output
users = [
{id: 1, account_id: 1, account_name: "administrator"},
{id: 2, account_id: 2, account_name: "moderator"},
{id: 3, account_id: 1, account_name: "administrator"}
]
It is slightly redundant but makes your life easier in the UI and doesn't cost much in the server.

Related

how to loop my react data, its not showing my data

I makes crud with react but i have trouble when try to displaying from data table. please help me
this my code
my conn to api
this my looping data
looping code
this the console log
console log
I saw that you make an array which contains a lot of arrays. Is this your expectation?
rowsData = [
[{ DocumentID: 1, DocumentName: 2, status: 3, navigation: 4 }],
[{ DocumentID: 1, DocumentName: 2, status: 3, navigation: 4 }]
]

AngularJS filtering using external JSON

I've been wondering for some long time, how can I filter something like this. Here is my situation:
I have one JSON table like this:
var cars = [{
"id": 1,
"brand": "Ford",
"model": "Focus",
"generation": "2.0TDCi",
"version": "hatchback, 3 drzwi",
"mileage": 100,},{
"id": 2,
"brand": "Volkswagen",
"model": "Golf",
"generation": "III",
"version": " 1.9 TDI, hatchback, 4 drzwi",
"mileage": 14,}];
And I'm using this kind of generating table using data from JSON:
<tr data-ng-repeat="car in cars" (...)
I've also have a dropdown with multiselection:
<div ng-dropdown-multiselect="" options="exampleBrand" selected-model="exampleBrandModel" extra-settings="exampleSettings"></div>
Things which are imported into this selector are from JSON file:
$scope.exampleBrand = [{id: 1, label: "Ford"}, {id: 2, label: "Ferrari"}, {id: 3, label:"Suzuki"},
{id: 4, label:"Fiat"}, {id: 5, label:"Aston Martin"}, {id: 6, label:"Opel"}];
The model of thing which are selected lands here:
$scope.exampleBrandModel = [];
For example if I select "Ford", the JSON file with model looks like this (checked with
{{ exampleBrandModel| json }}
):
[
{
"id": "Ford"
}
]
And my question is. How can I use angular's filter option to make it working?
I was using something like that which was not working:
<tr data-ng-repeat="car in cars |filter: {exampleBrandModel : id}">
I want to have situation like this:
At start I get whole table with cars listed in and then I select "Ford". Now every row in table without "Ford" word should be filtered out.
Do someone know how can I do that?

how to merge similar values in normalizr function?

I have unusual response from server like this
[
{
id: 1,
name: "Alexandr",
children: [
{
id: 2,
name: "Stephan"
},
{
id: 3,
name: "Nick"
}
]
},
{
id: 4,
name: "David",
children: [
{
id: 3,
name: "Nick"
},
{
id: 6,
name: "Paul"
}
]
}
]
i would like to normalize this response to receive a diction with all people. So, i use normalizr go flat this
const people= new Schema('people');
people.define({
Children: arrayOf(people),
NotOwnChildren: arrayOf(people)
});
let normalized = normalize(response.data, arrayOf(people));
but doing like this i get an error
"When merging two people, found unequal data in their "Children" values. Using the earlier value."
How can i adjust normalizr to merge people with same id (update entities with newest data)?
It looks like you're getting two people that have differing values for one of their keys (I'm assuming your example input is truncated).
For Normalizr#2:
You can use a custom mergeIntoEntity function to resolve the issue manually.
For Normalizr#>=3.0.0, you'll need use mergeStrategy.

sorting collection objects into directive by id with recursion

I've been checking some posts about recursive directives in here, but none of them seems to work for me.
Basically my case is the following:
Having a collection of objects as follows:
[
{id: 1, parentid:null, text: 'something 1'},
{id: 2, parentid:null, text: 'something 2'},
{id: 3, parentid:1, text: 'something 3'},
{id: 4, parentid:1, text: 'something 4'},
{id: 5, parentid:2, text: 'something 5'},
{id: 6, parentid:3, text: 'something 6'},
{id: 7, parentid:4, text: 'something 7'},
{id: 8, parentid:5, text: 'something 8'}
]
Of course there are more keys, but these are needed to place the logic.
Basically I something which renders the following:
<ul>
<li>Parent id: n
<ul>
<li>Children of n</il>
</li>
</ul>
So my first guess was that I need a directive which renders a similar version of itself each time there is a child occurence, but I'm sure even how to attack this. I just need a unknown number of heritance refers to the child of the upper level.
Any approach or pattern remendation to face this?
I think the easiest way is to first organise the data into hierarchical structure like this:
[
{
id: 1,
parentid:null,
text: 'something 1',
children: [
{id: 3, parentid:1, text: 'something 3'},
{id: 4, parentid:1, text: 'something 4'},
]
},
{
id: 2,
parentid:null,
text: 'something 2',
children: [
{id: 5, parentid:2, text: 'something 5'}
]
},
]
Then rendering with ng-repeat with nested ng-repeat is quite obvious.
If you have more levels in this hierarchy, then thinking about some kind of recursion may be a solution.
EDIT:
The simplest way is to reorganise data for rendering purposes in an object, where indexes (property names) are ids, and values are arrays with this node children. Then, to get children of each id you can get them by dictVar[parentId].
Data transformation is quite simple and can be done various ways, e.g.:
var dataDict = {};
angular.forEach(data, function (item) {
var id = item.parentid || 0;
var items = $scope.dataDict[id] || [];
items.push(item);
dataDict[id] = items;
});
After that in dataDict you have:
{
"0": [
{"id": 1, "parentid": null, "text": "something 1"},
{"id": 2, "parentid": null, "text": "something 2"}
],
"1": [
{"id": 3, "parentid": 1, "text": "something 3"},
{"id": 4, "parentid": 1, "text": "something 4"}
],
"2": [
{"id": 5, "parentid": 2, "text": "something 5"}
],
"3": [
{"id": 6, "parentid": 3, "text": "something 6"}
],
"4": [
{"id": 7, "parentid": 4, "text": "something 7"}
],
"5": [
{"id": 8, "parentid": 5, "text": "something 8"}
]
}
You can leave it like this or transform it even further to get fully hierarchical structure.
Then, to render the list you can use technique described here: http://sporto.github.io/blog/2013/06/24/nested-recursive-directives-in-angular/

Anuglar same criteria multiple checkboxes

I have 3 arrays:
brands = [
{'id': 1, 'name': 'SOME BRAND'}
....
]
sizes [
{'id': 1, length: 12}
....
]
items [
{id: 1, brand: 1, size: 1}
....
]
Brands and sizes become checkboxes. I need to set up filter for items by brands and sizes. I don't have a clue how. Please help.
create your own filter https://docs.angularjs.org/api/ng/filter/filter
and in the callback do the desired stuff.

Resources