Using angularjs filter and _.groupBy - javascript

Here's a simple example I created to replicate my issue. In my controller, I have an array of people:
$scope.people = [
{ name: 'fred', age: 20 },
{ name: 'bob', age: 22 },
{ name: 'jane', age: 24 },
{ name: 'mary', age: 22 },
{ name: 'ben', age: 24 },
{ name: 'sarah', age: 21 },
];
I have a filter defined:
.filter('grouped', function () {
return function (input) {
return _.groupBy(input, 'age');
}
})
You may notice that I'm using Lo-Dash to do the group by.
In my view I have a list defined:
<div class="list" ng-repeat="personGroup in people | grouped">
{{ $index }}
<div class="list" ng-repeat="person in personGroup">
{{ person.name }}
</div>
</div>
I get the result I'm after but I get a heap of errors in my developer console.
https://docs.angularjs.org/error/$rootScope/infdig?p0=10
I understand why I'm getting the error. This is explained in detail in the above link. I just don't know the proper way of achieving the result I'm after.

As you are creating new Array-objects when grouping the people, I would not use a filter at all. The easiest solution would be to do the grouping inside your controller:
...
$scope.groups = _.groupBy($scope.people, 'age');
...
Your ng-repeat attribute would then read like:
ng-repeat="personGroup in groups"

What version of angular are you using? I'm not getting any error:
http://plnkr.co/edit/bbDGjHWMGZx5GmNcggaw?p=preview

Related

Best way to loop Obj data in HTML document with JS?

I'm developing a simple SPA framework. I have a problem. I want to render my Obj data in HTML. Below is my code and my online example
var data = {
for: {
animal: [{
name: 'dog',
alive: 'false'
},
{
name: 'cat',
alive: 'true'
}
],
human: [{
name: 'bob',
sex: 'male'
},
{
name: 'alice',
sex: 'female'
}
]
}
};
<html>
<div id="app">
<ol>
<li np-for="animal">
<np tag="text-for" data="name"></np><br>
<np tag="text-for" data="alive"></np>
</li>
</ol>
</div>
</html>
best way to solve it?
If you are not using a framework, then I suggest you using jQuery, so the full code looks like this
let data = {
animals : [
{ name: 'dog', alive : 'false'},
{ name: 'cat', alive : 'true'}
]
};
let animalList = $('#animals');
data.animals.forEach(function(data) {
animalList.append(`<li>
<b>${data.name}</b>
<i>${data.alive}</i>
</li>`);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<div id="app">
<ul id="animals">
<!-- data will automatically generated by jQuery -->
</ul>
</div>
</html>
I suggest you to using let or const for static variable instead of var, read more var vs let vs const in JavaScript
Read more about jQuery

Why does '.includes' work on an object inside a looped array?

I was hoping someone could help me understand something about the '.includes' method.
My understanding was that this only worked on arrays? for e.g. myarray.includes('something').
But it also seems to work when you loop over the array and use it on an object for e.g:
var people = [
{
name: 'Joe',
age: 27
},
{
name: 'Rob',
age: 25
},
{
name: 'Dave',
age: 22
}
];
for(i=0; i<people.length; i++) {
console.log(people[i].name.includes('Joe')) // True
}
Can someone explain why this is?
Thanks,
Joe
Because name is of type string, which also has an includes method. You can read on that here.

How to watch for a model's deep changes, from templates?

I have a model on my scope, which is an object of objects. I have seen this, but I want to do this from the template as I have a filter defined on it.
var App = angular.module('app', []);
App.controller('myCtrl', function($scope) {
$scope.items = {
{ name: 'Cricket bat', cost: '2500', quantity: 0},
{ name: 'Football', cost: '1100', quantity: 0}
};
$scope.cartItems = {}; // This holds the items. I want quantity of each item separately so it's not an array.
I have defined a filter getPrice which calculates the price for the items in users cart.
And I have in the template:
{{ cartItems | getPrice }}
Is it possible to have the template update after any of the nested object value (ie. quantity of one of the items from the cart) changes? If yes, how?
Move the quantity field to the cartItem object
$scope.items = {
{ name: 'Cricket bat', cost: '2500'},
{ name: 'Football', cost: '1100'}
};
$scope.cartItems = {
{ name: 'Cricket bat', quantity: 3},
{ name: 'Football', quantity: 6}
};
Then update your getprice filter based on the above json. This should take care of your cost in the cart getting updated when a price of an item changes.
Seems like your strategy is not good overall.
An "object of objects" as you mean it { {id:1}, {id:2} } is just not valid javascript, and will generate an error. Choose an array of objects [ {id:1}, {id:2} ] or a true object { 1: {id:1}, 2: {id:2} }
#Blackhole is right, you don't need to watch anything, interpolation is part of angular.js core and does all that tricky watch stuff for you. Defining a cartItems variable, and interpoling it (with brackets {}) in a template, filtering it or not, will keep the interpolated value in sync with the variable value without you doing anything more. It's even two-ways bound (if you change model, variable will also change). You can verify the sync by removing temporiraly your filter : try to put {cartItems} in your template and update your cart, you'll see the template updated.
This model format would probably be more appropriate
$scope.items = [
{ name: 'Cricket bat', cost: '2500' },
{ name: 'Football', cost: '1100' }
];
$scope.cartItems = [
{ item: { name: 'Cricket bat', cost: '2500' }, quantity: 3 },
];

how to set a default value for angular ui-select

Question :
how to set default value to the angular ui-select
drop down values are fetched from object and object wont be having default value.
and ui-select should set the default value in Frontend.
eg:
drop down values are as follows
1 -all fruits
2 -apple
3 -banana
4 -water melon
value from 2 to 4 are derived from object sent from server.but Frontend need to set default value ie 1 - all fruits
Referring to the below example set via ui-select2 how to migrate this in ui-select?
<select ng-model="fID" class="select" ui-select2 data-placeholder="select fruit">
<option value="">All fruits</option>
<option ng-repeat="f in frits value="{{f.fID}}">{{f.name}}</option>
</select>
<ui-select theme="select2" ng-model="fruits.selected">
<ui-select-match placeholder="select please" allow-clear="false"> {{$select.selected.name}}
</ui-select-match>
<ui-select-choices repeat="f in fruits | filter:$select.search">
<div ng-bind-html="f.name | highlight: $select.search:'underline'"></div>
</ui-select-choices>
</ui-select>
http://plnkr.co/edit/a3KlK8dKH3wwiiksDSn2?p=preview
https://github.com/angular-ui/ui-select
Link :angular-ui/ui-select
you didnt use an id or something like that for option value so ui-select compares object address to understand if it is selected.
var p1 = { name: 'Adam', email: 'adam#email.com', age: 10 };
$scope.person = {selected: p1};
$scope.people = [
p1,
{ name: 'Amalie', email: 'amalie#email.com', age: 12 },
{ name: 'Wladimir', email: 'wladimir#email.com', age: 30 },
{ name: 'Samantha', email: 'samantha#email.com', age: 31 },
{ name: 'Estefanía', email: 'estefanía#email.com', age: 16 },
{ name: 'Natasha', email: 'natasha#email.com', age: 54 },
{ name: 'Nicole', email: 'nicole#email.com', age: 43 },
{ name: 'Adrian', email: 'adrian#email.com', age: 21 }
];
change plunker like this and you will have a default selected value.
to set the default value on view you can use ng-init and set first object as selected
In your controller add the following code:
$scope.fruits.selected = {name: 'All fruits'};
The above will set the default selected value to the drop down.
I found this working example: http://jsfiddle.net/NfPcH/28/
Angular code:
<a href="#" editable-select="user.status" e-ng-options="s.value as s.text for s in statuses">
{{ showStatus() }}
</a>
Controller:
app.controller('Ctrl', function($scope, $filter) {
$scope.user = {
status: 2
};
$scope.statuses = [
{value: 1, text: 'status1'},
{value: 2, text: 'status2'},
{value: 3, text: 'status3'},
{value: 4, text: 'status4'}
];
$scope.showStatus = function() {
var selected = $filter('filter')($scope.statuses, {value: $scope.user.status});
return ($scope.user.status && selected.length) ? selected[0].text : 'Not set';
};
});

how to have a working grid displaying data source from ajax with the grid?

As I have learned the tutorial about dgrid(a new dojo grid),I have learned the example code.
Let me pick one to list here:
require(["dgrid/Grid", "dojo/domReady!"], function(Grid){
var data = [
{ first: "Bob", last: "Barker", age: 89 },
{ first: "Vanna", last: "White", age: 55 },
{ first: "Pat", last: "Sajak", age: 65 }
];
var grid = new Grid({
columns: {
first: "First Name",
last: "Last Name",
age: "Age"
}
}, "grid");
grid.renderArray(data);
});
I Just want to know if we can displaying data from Ajax data source. How to implement it.
Use dgrid/OnDemandGrid together with dojo/store/JsonRest or dojo/store/Memory.
You can find a working example in my answer to Is it possible to filter data in a dgrid like you can in a datagrid?: http://jsfiddle.net/phusick/7gnFd/

Categories

Resources