Dropdown default selection in Angular - html

I have following dropdown implementation in Angular. But I want to display the Paris as a default , but it shows None even though I assign value as 1 as follows.
.html
<p-dropdown [options]="labels" [(ngModel)]="selectedCity" optionLabel="name" (onChange)="cityChanged($event.value)"></p-dropdown>
.ts
interface City{
name: string;
value: number;
}
export class CityComponent {
selectedCity: number = 1;
constructor() {
this.labels = [
{name: 'None', value: 0},
{name: 'Paris', value: 1},
{name: 'Rome', value: 2},
{name: 'London', value: 3},
{name: 'Istanbul', value: 4},
{name: 'Amsterdam', value: 5},
{name: 'Moscow', value: 6},
{name: 'Zurich', value: 7}
];
}
cityChanged(city : City)
{
this.selectedCity = city.value
}
}

This is happening because the dropdown expects the selected value to match one of your options. Since you are storing your options as objects, but your value as a number, it is unable to find a match. The simplest approach to fix this would be to store the whole object as the selectedCity, grabbing just the value once it is needed:
export class CityComponent {
selectedCity = {name: 'Paris', value: 1};
constructor() {
this.labels = [
{name: 'None', value: 0},
{name: 'Paris', value: 1},
{name: 'Rome', value: 2},
{name: 'London', value: 3},
{name: 'Istanbul', value: 4},
{name: 'Amsterdam', value: 5},
{name: 'Moscow', value: 6},
{name: 'Zurich', value: 7}
];
}
getSelectedValue(): number {
return this.selectedCity.value;
}
cityChanged(city : City) {
this.selectedCity = city;
}
}

Related

Angular - Display data from 2 JSON in HTML

I'm having trouble displaying data from 2 interconnected JSON in Angular.
First JSON:
member = [
{ id: 1, name: 'shinta'},
{ id: 2, name: 'rahma'},
{ id: 3, name: 'john'}
]
Second JSON:
nest = [
{id: 1, amount: 2000, userid: 1},
{id: 2, amount: 3000, userid: 2},
{id: 3, amount: 5000, userid: 2},
{id: 4, amount: 1500, userid: 1},
{id: 5, amount: 2200, userid: 1},
{id: 6, amount: 12500, userid: 1},
{id: 7, amount: 7000, userid: 2},
{id: 8, amount: 8300, userid: 3},
{id: 9, amount: 2800, userid: 3},
{id: 10, amount: 9500, userid: 3}
]
How to view/bind data in HTML?
<ul *ngFor="let item of memberData, let i = index">
<li>{{ item.name }} <span>*this to view sum of user amount*</span></li>
</ul>
Please guide me to solve this problem. Thank you.
Use .map() to create new array with:
Duplicate object element of members (via ...x)
New field: totalAmount with .reduce() to perform aggregate sum.
this.memberData = this.member.map((x) => ({
...x,
totalAmount: this.nest
.filter((y) => y.userid == x.id)
.reduce((total: number, current) => (total += current.amount), 0),
}));
<ul *ngFor="let item of memberData; let i = index">
<li>
{{ item.name }} <span>{{ item.totalAmount }}</span>
</li>
</ul>
Demo on StackBlitz

How to transpose array of objects in TypeScript?

I am having an array of objects as below:
finalList = [
[{name: john}, {name: max}, {name: rob}],
[{id: 1}, {id: 2}, {id: 3}],
[{gender: M}, {gender: F}, {gender: M}],
]
I need the array to transpose like this:
finalList = [
{name: john, id: 1, gender: M},
{name: john, id: 1, gender: M},
{name: john, id: 1, gender: M}
]
The actual array of object is in nested array. Please help me guiding to transpose the array in TypeScript.
Here's a nice functional way. It assumes each array in finalList has the same length and same keys (so no error handling).
const finalList = [
[{name: "john"}, {name: "max"}, {name: "rob"}],
[{id: 1}, {id: 2}, {id: 3}],
[{gender: "M"}, {gender: "F"}, {gender: "M"}],
];
console.log(finalList);
// this is a trick to create an array of a specific size with unique objects inside it
// the fill is necessary to iterate over the holed array (https://stackoverflow.com/q/40297442/2178159)
// fill({}) won't work since it's a single object ref that will be shared
const results = new Array(finalList.length).fill(null).map(() => ({}));
finalList.forEach(group => {
group.forEach((obj, i) => {
Object.assign(results[i], obj);
})
});
console.log(results);

Trouble formatting json objects with lodash _.groupBy

I'm having trouble reformatting an object in order to group by lists.
// input
{
'M': [
{name: Bob, id: 1},
{name: John, id: 2},
{name: John, id: 3},
],
'F': [
{name: Liz, id: 4},
{name: Mary, id: 5},
{name: Mary, id: 6},
]
}
// desired output
{
'M': [
'Bob': [ {name: Bob, id: 1},]
'John': [ {name: John, id: 2}, {name: John, id: 3} ]
],
'F': [
'Liz': [ {name: Liz, id: 4} ]
'Mary': [ {name: Mary, id: 5}, {name: Mary, id: 6} ]
]
}
My current script is only returning the 'M' key and I'm not what is causing it
for (var key in obj) {
var data = _.groupBy(obj[key], 'name')
return data;
}
I've also tried
Object.keys(obj).forEach(obj, key => {
var data = _.groupBy(obj[key], 'name')
return data;
})
but it throws TypeError: #<Object> is not a function
You can use mapValues to group each gender groups by their names through groupBy.
var output = _.mapValues(input, names => _.groupBy(names, 'name'));
var input = {
'M': [
{name: 'Bob', id: 1},
{name: 'John', id: 2},
{name: 'John', id: 3},
],
'F': [
{name: 'Liz', id: 4},
{name: 'Mary', id: 5},
{name: 'Mary', id: 6},
]
};
var output = _.mapValues(input, names => _.groupBy(names, 'name'));
console.log(output);
body > div { min-height: 100%; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
Use _.forOwn since you want to iterate its own properties.
_.forOwn(obj, function(key, val) {
var ret = {};
ret[key] = _.groupBy(val, 'name');
return ret;
});

ngModel Acting Strange - Angular2

myList: any;
ngOnInit(){
this.myList = [
{id: 1, name: 'a'},
{id: 2, name: 'b'},
{id: 3, name: 'c'},
{id: 4, name: 'd'},
];
}
In my html
<input *ngFor="let l of myList" [(ngModel)]="l.name" name="{{l.id}}" />
It's working good as below:
Chrome Dev:
Then when I call another service in my ngOnInit like below:
myList: any;
ngOnInit(){
this.myList = [
{id: 1, name: 'a'},
{id: 2, name: 'b'},
{id: 3, name: 'c'},
{id: 4, name: 'd'},
];
this.outletService.getAll().then(outlets => {
this.outlets = outlets;
});
}
Suddenly, there is no value in the input as you see below: My html code is the same.
What could possibly be happened? How can I get the value to appear in the inputs?
Here is the outletService .getAll()
getAll() {
return new Promise(resolve => {
let headers = new Headers({
'Content-Type': 'application/json'
});
let options = new RequestOptions({ headers: headers });
this.http.get(this.host + '/outlets', options)
.subscribe(data => {
resolve(data.json()); //Return array of objects
});
});
}
Here is the return from the outletService:
There is no error in the console, and I want the property name from this.myList, not outletName from this.outlets.
Update
What's more interesting is: I don't even need to call another service:
If i just assign new array to this.outlets, it won't work, like this case:
myList: any;
outlets: any;
ngOnInit(){
this.myList = [
{id: 1, name: 'a'},
{id: 2, name: 'b'},
{id: 3, name: 'c'},
{id: 4, name: 'd'},
];
this.outlets = [
{id: 1, name: 'a'},
{id: 2, name: 'b'},
{id: 3, name: 'c'},
{id: 4, name: 'd'},
];
}
And add another line to the html file.
<input *ngFor="let l of myList" [(ngModel)]="l.name" name="{{l.id}}" />
<input *ngFor="let o of outlets" [(ngModel)]="o.outletName" name="{{o.id}}" />
You should change your template. There is no name attribute on your returned data:
<input *ngFor="let l of myList" [(ngModel)]="l.outletName" name="{{l.id}}" />
Ohh, well.. Gunter already mentioned this in his comment :)
In fact, the ngModel doesn't give any values to the input because the id properties of the two objects are the same!
If I change from this:
myList: any;
outlets: any;
ngOnInit(){
this.myList = [
{id: 1, name: 'a'},
{id: 2, name: 'b'},
{id: 3, name: 'c'},
{id: 4, name: 'd'},
];
this.outlets = [
{id: 1, name: 'a'},
{id: 2, name: 'b'},
{id: 3, name: 'c'},
{id: 4, name: 'd'},
];
}
To this:
myList: any;
outlets: any;
ngOnInit(){
this.myList = [
{id: 1, name: 'a'},
{id: 2, name: 'b'},
{id: 3, name: 'c'},
{id: 4, name: 'd'},
];
this.outlets = [
{id: 5, name: 'a'},
{id: 6, name: 'b'},
{id: 7, name: 'c'},
{id: 8, name: 'd'},
];
}
Then it works! ask me why? I don't know.. If someone can explain would be great!

Load two different Json dat in Odd and Even rows - ngGrid- AngularJs

I am trying to load two different json data for even rows and odd rows like what we see here. I did try multiple sources as a refernce using ng-grid, but none has any solution. Kindly tell me the possibility on the same. Is it possible to do the same.
HTML
<div class="list-view-body">
<div class="list-view" ng-grid="settings"></div>
</div>
AngularJS
$scope.settings = {
data: 'records',
enableColumnResize: false,
enablePaging: true,
enableRowSelection: false,
rowHeight: 35,
headerRowHeight: 35,
totalServerItems: 'totalServerItems',
pagingOptions: {
pageSizes: [15, 20, 50, 80, 100],
pageSize:15,
currentPage: 0
},
showFooter: true,
footerRowHeight: 0,
columnDefs: [
{field: 'id', displayName: '', width: 25, cellTemplate: '<span class="caret-right"></span>' },
{field: 'reports', displayName: 'Reports', width: 75 },
{field: 'opportunityName', displayName: 'Opportunity', width: 250},
{field: 'proposalId', displayName: 'Proposal ID', width: 95},
{field: 'startDate', displayName: 'Start date', width: 90},
{field: 'endDate', displayName: 'End date', width: 90},
{field: 'amount', displayName: 'Amount', cellTemplate: '<div class="ngCellText"><span>{{row.entity.amount | currency:\'USD$\'}}</span></div>' },
{field: 'alertss', displayName: 'Alerts'},
{field: 'healths', displayName: 'Health'},
{field: 'commentss', displayName: 'Comments' },
{field: 'flag', displayName: 'Flag', cellTemplate: '<div class="ngCellText"><span class="action-icon lv-flag true"></span></div>' }
]
};
I think it would reach to mix the two data json sources in the controller, intercalate them and displaying the result using a ng-grid directive ... something like this
// main.js
var app = angular.module('myApp', ['ngGrid']);
app.controller('MyCtrl', function($scope) {
$scope.myOddData = [{name: "Moroni Odd", age: 50},
{name: "Tiancum Odd", age: 40},
{name: "Jacob Odd", age: 20},
{name: "Nephi Odd", age: 30},
{name: "Enos Odd", age: 34}];
$scope.myEvenData = [{name: "Moroni Even", age: 51},
{name: "Tiancum Even", age: 43},
{name: "Jacob Even", age: 27},
{name: "Nephi Even", age: 23},
{name: "Enos Even", age: 34}];
$scope.result = $scope.myOddData.reduce(function(arr, v, i) {
return arr.concat(v, $scope.myEvenData[i]);
}, []);
$scope.gridOptions = { data: 'result' };
});
Here the related Plunker
http://plnkr.co/edit/MyV5pBXK4rQEmbfbCjgL