Parsing Uneven data/ json object using ng-repeat - javascript

fiddle here http://jsfiddle.net/prantikv/1nvdzv24/9/
i have some uneven data like so
[{
"fname": "Tonja", //common
"lname": "Mize",
"tel": "(963)784-1098",
"address": "3999 Quis Ln",
"city": "Sebring",
"state": "MI",
"zip": 76593
},
{
"fname": "Stella", //common
"Othername": "Lester",
"mobile": "(936)898-2886"
}];
notice only the fname property is common between the two objects
so when i do this
<li ng-repeat="(key,val) in populationList | filter:name">
{{ val.**fname**}}
</li>
i do get the fname but the data is uneven so i cannot figure out how to go through over each object. also the length of the object is different as well.
what i want to do is to filter the data over a select list
<select ng-model="name">
<option value="Tonja" selected="Tonja">Tonja</option>
<option value="Stella">Stella</option>
</select>
but i am unable to figure out a way to display the unmatched properties of objects
is there a way i get all the key:value pairs on the sub data dynamically?

WORKING DEMO
Your Html,
<div ng-app='app'>
<div ng-controller="DemoCtrl">
<select ng-options="item.fname for item in populationList | fieldList:'fname'" ng-model="myItem" ng-change="changeSelection(myItem)">
</select>
<li ng-repeat="key in availableKeys">
{{selectedObject[key]}}
</li>
</div>
</div>
JS
angular.module('filters',[]).
filter('fieldList', function() {
return function(populationList, parameter) {
var filteredArray = [];
angular.forEach(populationList, function(value, index) {
if(value.hasOwnProperty(parameter)) {
filteredArray.push(value);
}
});
return filteredArray;
};
});
angular.module('app',['filters'])
.controller('DemoCtrl', function($scope) {
$scope.changeSelection = function(item) {
$scope.selectedObject = item;
$scope.availableKeys = Object.keys($scope.selectedObject);
};
$scope.populationList = [{
"fname": "Tonja", //common
"lname": "Mize",
"tel": "(963)784-1098",
"address": "3999 Quis Ln",
"city": "Sebring",
"state": "MI",
"zip": 76593
},
{
"fname": "Stella", //common
"Othername": "Lester",
"mobile": "(936)898-2886"
}];
});

Related

Custom sorting of objects by key in ng-repeat

I have an object stored in $scope.addresscards inside a controller. The js is given below:
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.addresscards = {
"work_address": {
"location":"workLoc",
"address": "workAddr",
"flat_no": "worknumber",
"landmark": "workLandmark"
},
"random1_address": {
"location":"someLoc",
"address": "SomeAddr",
"flat_no": "Somenumber",
"landmark": "someLandmark"
},
"home_address": {
"location":"homeLoc",
"address": "homeAddr",
"flat_no": "homenumber",
"landmark": "homeLandmark"
},
"random2_address": {
"location":"someLoc2",
"address": "SomeAddr2",
"flat_no": "Somenumber2",
"landmark": "someLandmark2"
}
};
}
I'm using ng-repeat to display the addresses. Here is the HTML:
<div ng-controller="MyCtrl">
<ul ng-repeat="(addressKey,addressVal) in addresscards">
<li>{{addressKey}} has :: {{addressVal.location}},{{addressVal.address}}, {{addressVal.location}}, {{addressVal.address}}</li>
</ul>
</div>
My output is:
home_address has :: homeLoc, homeAddr, homeLoc, homeAddr
random1_address has :: someLoc, SomeAddr, someLoc, SomeAddr
random2_address has :: someLoc2, SomeAddr2, someLoc2, SomeAddr2
work_address has :: workLoc, workAddr, workLoc, workAddr
I want to display the output such that, if the object has home_address it should be displayed 1st, then if the object has work_address it should be displayed. Then rest of the object should be showed alphabetically.
Here is expected result that I want to display:
home_address has :: homeLoc, homeAddr, homeLoc, homeAddr
work_address has :: workLoc, workAddr, workLoc, workAddr
random1_address has :: someLoc, SomeAddr, someLoc, SomeAddr
random2_address has :: someLoc2, SomeAddr2, someLoc2, SomeAddr2
I tried it using orderBy, It doesn't work on objects. How do I achieve this?
You can add a property to your address objects
$scope.addresscards = {
"work_address": {
"location":"workLoc",
"address": "workAddr",
"flat_no": "worknumber",
"landmark": "workLandmark",
"sort" : "2"
},
"random1_address": {
"location":"someLoc",
"address": "SomeAddr",
"flat_no": "Somenumber",
"landmark": "someLandmark"
},
"home_address": {
"location":"homeLoc",
"address": "homeAddr",
"flat_no": "homenumber",
"landmark": "homeLandmark",
"sort" : "1"
},
"random2_address": {
"location":"someLoc2",
"address": "SomeAddr2",
"flat_no": "Somenumber2",
"landmark": "someLandmark2"
}
};
and in your ng-repeat you can orderBy multiple fields first by sort to display home and work address first and then by address key for alphabetical order.
<ul ng-repeat="(addressKey,addressVal) in addresscards | orderBy:['sort','addressKey']">
<li>{{addressKey}} has :: {{addressVal.location}},{{addressVal.address}}, {{addressVal.location}}, {{addressVal.address}}</li>
</ul>
or in your controller you can sort all other addresses and append home and work address to the beginning of your list.
Plunker

Swap rows/indexes within a JavaScript array using AngularJS

I have a custom directive that is holding an array of JavaScript objects.
The object is a little complex and lengthy but I will display something similar to point out my problem:
A JSON.stringify of this displays the following:
[
{
"Id": 1,
"Name": "John Doe",
"EMail": "john#doe.com"
},
{
"Id": 2,
"Name": "Jim Doe",
"EMail": "jim#doe.com"
},
{
"Id": 3,
"Name": "Jeff Doe",
"EMail": "jeff#doe.com"
}
]
I am further using ng-repeat to display the values in a tabular form on my HTML.
The values are coming from an API call that fetches them from a database.
I want to swap - say the entire Object with Id 1 with the entire Object with Id 3 so that during my tabular display I can see Id 3 object details first and Id 1 object details last, without breaking any functionality.
What would be the best possible solution to do this within the frontend itself?
How about just swapping them using a temp variable?
var arr = [{"Id":1,"Name":"John Doe","EMail":"john#doe.com"},
{"Id":2,"Name":"Jim Doe","EMail":"jim#doe.com"},
{"Id":3,"Name":"Jeff Doe","EMail":"jeff#doe.com"}]
var tmpObj = arr[0];
arr[0] = arr[2];
arr[2] = tmpObj;
If you want to reverse the array, use Array.prototype.reverse()
var app = angular.module("myApp", []);
app.controller("myController", function($scope) {
var arr = [
{
"Id": 1,
"Name": "John Doe",
"EMail": "john#doe.com"
},
{
"Id": 2,
"Name": "Jim Doe",
"EMail": "jim#doe.com"
},
{
"Id": 3,
"Name": "Jeff Doe",
"EMail": "jeff#doe.com"
}
];
$scope.array = arr.reverse();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myController">
<div ng-repeat="item in array">
{{item.Id}} - {{item.Name}} - {{item.EMail}}
</div>
</div>
</div>

How to get json array value and display in dropdwon list in angularjs?

{"id":1,"firstName":"John1","lastName":"Doe1","**accountIds**":[12345,12346,12347],"recipients":[{"accountNumber":22222,"firstName":"Mary1","lastName":"Jane1"},{"accountNumber":33333,"firstName":"Mary2","lastName":"Jane2"}]}
display "accountIds" is dropdown list.
Please see jsfiddle attached http://jsfiddle.net/HB7LU/13213/.
You need to target the accountIds by using dot notation.
HTML
<div ng-controller="MyCtrl">
<select>
<option ng-repeat="item in items.accountIds">{{item}}</option>
</select>
</div>
JS/Angular
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.items = {
"id": 1,
"firstName": "John1",
"lastName": "Doe1",
"accountIds": [12345, 12346, 12347],
"recipients": [{
"accountNumber": 22222,
"firstName": "Mary1",
"lastName": "Jane1"
}, {
"accountNumber": 33333,
"firstName": "Mary2",
"lastName": "Jane2"
}]
}
}

How to dynamically populate display objects in Angular JS based on properties from the JSON object.?

I am reading the below json value from a module.js
.controller('home.person',['$scope','$filter','personResource',function($scope,$filter,personResource) {
$scope.searchPerson = function() {
var params = $scope.search || {};
params.skip=0;
params.take =10;
$scope.personDetails =
{
"apiversion": "0.1",
"code": 200,
"status": "OK",
"mydata": {
"myrecords": [
{
"models": [
{
"name": "Selva",
"dob": "10/10/1981"
}
],
"Address1": "ABC Street",
"Address2": "Apt 123",
"City": "NewCity1",
"State": "Georgia"
},
{
"models": [
{
"name": "Kumar",
"dob": "10/10/1982"
}
],
"Address1": "BCD Street",
"Address2": "Apt 345",
"City": "NewCity2",
"State": "Ohio",
"Country":"USA"
},
{
"models": [
{
"name": "Pranav",
"dob": "10/10/1983"
}
],
"Address1": "EFG Street",
"Address2": "Apt 678",
"City": "NewCity3",
"State": "NewYork",
"Country":"USA",
"Zipcode" :"123456"
}
]
}
}
}
}])
Now i am able to statically build the UX. But my each record set's key value pair count is different. So i want to build my html dynamically as per the current record set's count.Country & Zipcode is not exist in all records so i need to build dynamically the build and populate the html output.Most of the time, my json output is dynamic. Instead of persondetails, i may get the json output of a product details instead of PersonDetails.
<div ng-show="personDetails.mydata.myrecords.length > 0" ng-repeat="recordSingle in personDetails.mydata.myrecords">
<div >
<span >Address1: {{recordSingle.Address1}}</span>
<span >Address2: {{recordSingle.Address2}}</span>
<span>City: {{recordSingle.City}}</span>
<span>State: {{recordSingle.State}}</span>
<span>Country: {{recordSingle.Country}}</span>
<span>Zipcode: {{recordSingle.Zipcode}}</span>
</div>
</div>
One way is to use ng-if statement, for the optional span elements:
<span ng-if="recordSingle.Address1">Address1: {{recordSingle.Address1}}</span>
[Update #1: updated based on revised comments to question]
[Update #2: fixed typos in function and included plunkr]
I now understand that you want to dynamically build the display objects based on properties from the JSON object. In this case, I would iterate through the properties of the object. I would use a function to produce this array of properties for each object so that you can filter out any prototype chains. I would also remove out any unwanted propoerties, such as the internal $$hashKey and perhaps the array objects e.g.
In your controller:
$scope.getPropertyNames = getPropertyNames;
function getPropertyNames(obj) {
var props = [];
for (var key in obj) {
if (obj.hasOwnProperty(key) && !angular.isArray(obj[key]) && key !== '$$hashKey') {
props.push(key);
}
}
return props;
}
Then in your HTML view:
<div ng-repeat="record in personDetails.mydata.myrecords">
<div ng-repeat="prop in getPropertyNames(record)">
<span ng-bind="prop"></span>: <span ng-bind="record[prop]"></span>
</div>
</div>
This works for me... see this plunker. It is displaying each of the properties of the object in the array dynamically (you could have any property in the object). Is this not what you are trying to achieve?

Set and Display current Data on ng-click?

I'm using Yeoman - angular generator.
JSBin: JSBin Link
I have a simple list of airports being set from a factory angApp.factory("Airports", function() {}); and displayed from ng-repeat <ul ng-repeat="airport in airports.detail">.
I would like to have an interaction that when each link is clicked it will match the airport code and display it in a new paragraph tag <p class="current">Current: {{currentAirport.name}}</p>.
Why wont the setAirport(airport.code) function set the currentAirport.name(or display?) when airport link is clicked in html?
Controller
angular.module("ang6App")
.controller("AirportsCtrl", function ($scope, Airports) {
$scope.formURL = "views/_form.html";
$scope.currentAirport = null;
$scope.airports = Airports;
$scope.setAirport = function(code) {
$scope.currentAirport = $scope.airports[code];
};
});
Factory Service in the same module
angApp.factory("Airports", function() {
var Airports = {};
Airports.detail = {
"PDX": {
"code": "PDX",
"name": "Portland International Airport",
"city": "Portland",
"destinations": [
"LAX",
"SFO"
]
},
"STL": {
"code": "STL",
"name": "Lambert-St. Louis International Airport",
"city": "St. Louis",
"destinations": [
"LAX",
"MKE"
]
},
"MCI": {
"code": "MCI",
"name": "Kansas City International Airport",
"city": "Kansas City",
"destinations": [
"LAX",
"DFW"
]
}
};
return Airports;
});
HTML
<div class="container" ng-controller="AirportsCtrl">
<ul ng-repeat="airport in airports.detail">
<li>{{airport.code}} -- {{airport.city}} </li>
</ul>
<p class="current"> current: {{currentAirport.name}}</p>
</div>
Your setAirport function should be written as:
$scope.setAirport = function (code) {
$scope.currentAirport = $scope.airports.detail[code];
};
But then, this could be simplified by passing the actual airport object directly:
<a href ng-click="setAirport(airport)">{{airport.code}}</a>
$scope.setAirport = function (airport) {
$scope.currentAirport = airport;
};

Categories

Resources