I have a pandas Series that I have converted into JSON for Angular to display in a table. The issue is that the key values are a python list under a string type. How can I convert the key into an array for Angular?
JSON:
{
"result": {
"('', '100.83.105.90')": 1,
"('AS1124 Universiteit van Amsterdam', '145.18.162.122')": 2,
"('AS11796 Airstream Communications, LLC', '64.33.197.15')": 1,
"('AS16276 OVH SAS', '51.75.201.126')": 1,
"('AS209 CenturyLink Communications, LLC', '174.27.155.12')": 1,
"('AS22394 Cellco Partnership DBA Verizon Wireless', '174.241.2.88')": 1,
"('AS24608 Wind Tre S.p.A.', '37.227.23.201')": 1,
"('AS3329 Vodafone-panafon Hellenic Telecommunications Company SA', '5.55.162.202')": 1,
"('AS3352 Telefonica De Espana', '80.24.64.41')": 1,
"('AS6128 Cablevision Systems Corp.', '69.116.62.88')": 1,
"('AS6805 Telefonica Germany', '2.240.20.127')": 1,
}
In Angular:
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col" >{{selectedGroup}}</th>
<th scope="col">{{selectedColumn}}</th>
<th scope="col">Hits</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of mvaHits | keyvalue">
<td>{{item.key[0]}}</td>
<td>{{item.key[1]}}</td>
<td>{{item.value}}</td>
</tr>
</tbody>
</table>
What it looks like:
How can I fix this?
Appreciate the help :)
The best solution would be to export the data from Python in a proper JSON format. You could then parse the array as a real Javascript array using JSON.parse().
If you can't adjust mvaHits, this should parse the Python array as a Javascript array and let you access the elements in the array. Note that this wouldn't work in all cases, especially if the strings in your array had commas. I would recommend not doing these conversions in the HTML for the sake of clarity and cleanliness, but rather when you load mvaHits for the first time. But this should work:
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col" >{{selectedGroup}}</th>
<th scope="col">{{selectedColumn}}</th>
<th scope="col">Hits</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of mvaHits | keyvalue">
<td>{{item.key.slice(1,-1).split(', ').map((s) => s.slice(1,-1))[0]}}</td>
<td>{{item.key.slice(1,-1).split(', ').map((s) => s.slice(1,-1))[1]}}</td>
<td>{{item.value}}</td>
</tr>
</tbody>
</table>
Breaking it down:
item.key
.slice(1,-1) // Removes the first and last characters in the string, removing the ()
.split(', ') // Splits the string into an array using ', ' as the delimiter
.map((s) => s.slice(1,-1)) // Removes the quotes from the strings in the array
[0] // access the first element of the new array
Thanks to #zeterain for helping realize split/slice/etc can be applied directly to item.key.
Solution:
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col" >{{selectedGroup}}</th>
<th scope="col">{{selectedColumn}}</th>
<th scope="col">Hits</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of mvaHits | keyvalue">
<td>{{item.key | slice:1:-1 | split:", ":0}}</td>
<td>{{item.key | slice:1:-1 | split:", ":1}}</td>
<td>{{item.value}}</td>
</tr>
</tbody>
</table>
String splitting requires generating a custom pipe, instructions can be found here: https://stackoverflow.com/a/45205047/6575456
Slice pipe (default angular): https://angular.io/api/common/SlicePipe
I will propose you to use regular expressions in order to parse the keys. In this case is pretty simple. Regular expressions are a really powerful tool.
const data = {
"result": {
"('', '100.83.105.90')": 1,
"('AS1124 Universiteit van Amsterdam', '145.18.162.122')": 2,
"('AS11796 Airstream Communications, LLC', '64.33.197.15')": 1,
"('AS16276 OVH SAS', '51.75.201.126')": 1,
"('AS209 CenturyLink Communications, LLC', '174.27.155.12')": 1,
"('AS22394 Cellco Partnership DBA Verizon Wireless', '174.241.2.88')": 1,
"('AS24608 Wind Tre S.p.A.', '37.227.23.201')": 1,
"('AS3329 Vodafone-panafon Hellenic Telecommunications Company SA', '5.55.162.202')": 1,
"('AS3352 Telefonica De Espana', '80.24.64.41')": 1,
"('AS6128 Cablevision Systems Corp.', '69.116.62.88')": 1,
"('AS6805 Telefonica Germany', '2.240.20.127')": 1,
}
};
const regex = /\('(?<asn>.*)', '(?<ip>.*)'\)/;
const mvaHits = [];
for (const key of Object.keys(data.result)) {
const found = key.match(regex);
if (found) {
mvaHits.push({
asn: found.groups.asn,
ip: found.groups.ip,
hits: data.result[key]
});
}
}
console.log(mvaHits);
result
[ { asn: '', ip: '100.83.105.90', hits: 1 },
{ asn: 'AS1124 Universiteit van Amsterdam',
ip: '145.18.162.122',
hits: 2 },
{ asn: 'AS11796 Airstream Communications, LLC',
ip: '64.33.197.15',
hits: 1 },
{ asn: 'AS16276 OVH SAS', ip: '51.75.201.126', hits: 1 },
{ asn: 'AS209 CenturyLink Communications, LLC',
ip: '174.27.155.12',
hits: 1 },
{ asn: 'AS22394 Cellco Partnership DBA Verizon Wireless',
ip: '174.241.2.88',
hits: 1 },
{ asn: 'AS24608 Wind Tre S.p.A.', ip: '37.227.23.201', hits: 1 },
{ asn:
'AS3329 Vodafone-panafon Hellenic Telecommunications Company SA',
ip: '5.55.162.202',
hits: 1 },
{ asn: 'AS3352 Telefonica De Espana',
ip: '80.24.64.41',
hits: 1 },
{ asn: 'AS6128 Cablevision Systems Corp.',
ip: '69.116.62.88',
hits: 1 },
{ asn: 'AS6805 Telefonica Germany', ip: '2.240.20.127', hits: 1 } ]
html
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col" >{{selectedGroup}}</th>
<th scope="col">{{selectedColumn}}</th>
<th scope="col">Hits</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of mvaHits">
<td>{{item.asn}}</td>
<td>{{item.ip}}</td>
<td>{{item.hits}}</td>
</tr>
</tbody>
</table>
Although you can add code logic in angular template, as an advice try not abuse of these.
After executing a query, I received the following data which is in Json format which is in myDocData:
data: [
RowDataPacket {
updatedAt: 2020-01-03T18:30:00.000Z,
email: 'charles#hotmail.com',
name: 'charles',
money_spent: 1,
'avg(e.money_spent)': 1
},
RowDataPacket {
updatedAt: 2020-01-11T18:30:00.000Z,
email: 'ank#gmail.com',
name: 'ank',
money_spent: 10,
'avg(e.money_spent)': 6
}
]
angular code:
<table class="content-table" >
<thead>
<tr>
<th>EMAIL</th>
<th>NAME</th>
<th>money spent</th>
<th>UPDATED</th>
<th>AVERAGE</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of myDocData">
<td>{{item.email}}</td>
<td>{{item.name}}</td>
<td>{{item.money_spent}}</td>
<td>{{item.updatedAt}}</td>
<td>{{item.avg(e.money_spent)}}</td>
</tr>
</tbody>
</table>
Issue is that I am unable to display the value given by avg function
(other attributes are displayed correctly).
Change the line:
<td>{{item.avg(e.money_spent)}}</td>
to:
<td>{{item['avg(e.money_spent)']}}</td>
In JS, you can use square bracket notation to get properties of objects.
If you have the control over the back-end code then you can change the query which is returning "avg(e.money_spent)" to "avg(e.money_spent) as avg_money_spent" in this way will not be facing the issue and you can access the value using
<td>{{item.avg_money_spent}}</td>
Or you could also use the previous answer by #Viqas
I'm very new to ReactJS but I think I'm making some headway ...
I think I'm almost there but I've fallen down at what I think is near enough my final hurdle ... here's what I'm trying to achieve;
TV Show - Simpsons
Name: Bart Simpson, Gender: Male
Name: Homer Simpson, Gender: Male
Name: Ned Flanders, Gender: Male
TV Show - Flintstones
Name: Fred Flintstone, Gender: Male
Name: Barney Rubble, Gender: Male
Name: Wilma Flintstone, Gender: Female
I could have hundreds of these so I don't want to just build these in two React elements - so I've organised my data as such which I'm happy with;
var shows = [
{
id: 1,
show: 'Simpsons',
characters: [
{ id: 1, name: 'Bart Simpson', gender: 'Male'},
{ id: 2, name: 'Homer Simpson', gender: 'Male'},
{ id: 3, name: 'Ned Flanders', gender: 'Male'}
]
},
{
id: 2,
show: 'Flintstones',
characters: [
{ id: 1, name: 'Fred Flintstone', gender: 'Male'},
{ id: 2, name: 'Barney Rubble', gender: 'Male'},
{ id: 3, name: 'Wilma Flintstone', gender: 'Female'}
]
}
];
And then I'm building my data with a table as such:
const ShowsTable = (props) => {
return (
<div>
<h1>Show - {props.show}</h1>
<table>
<tr>
<th>Name</th>
<th>Gender</th>
</tr>
<tr>
<td>XXX</td>
<td>YYY</td>
</tr>
</table>
</div>
);
};
I've got this 'working' where I can get the shows name and anything from the main array but I can't get the data from the nested 'characters' child array
So XXX and YYY is where I would like to get the data for the names or gender, in my mind I should be able to do something like ...
{props.characters}
Or maybe getting the nested elements so something like
{props.characters.props.name}
But I can't figure this out or find any documentation for this - so is this a syntax error or am I missing something more fundamental ... maybe I'm asking the wrong question? I'm really not sure
If someone can point me in the right direction with an explanation or some documentation I'd be very grateful :-)
You can do something like:
const ShowsTable = (props) => {
return (
<div>
<h1>Show - {props.show}</h1>
<table>
<tr>
<th>Name</th>
<th>Gender</th>
</tr>
{props.characters.map((char, index) => (
<tr key={index}>
<td>{char.name}</td>
<td>{char.gender}</td>
</tr>
))}
</table>
</div>
);
};
I am an absolute newbie to angularjs and i have been making my hands dirty from the past 3 days. Now, the requirement is to convert a json string from the rest end point to tabular data. Here is the code i am trying.
$scope.getDataCatalogue = function(){
$http.get('http://api.geosvc.com/rest/US/84606/nearby?apikey=485a35b6b9544134b70af52867292071&d=20&pt=PostalCode&format=json')
.success(function(data, status, headers, config){
//do something with your response
$scope = data;
})
.error(function(error){
console.log("not world");
});
}
$scope.getDataCatalogue = function(){
alert('getDataCatalogue');
}
Now,how can i convert the json to grid from the data. Is this the right way to approach the problem.
If you have a fixed structure coming out of the data then you can simply make use of ng-repeat to iterate through the object(data) and display it on your pre-created table. Fiddle
Example shown below:
Considering this is your object which your assigning to a $scope variable name people. $scope.people = data;
[
{
id: 1,
firstName: "Peter",
lastName: "Jhons"
},
{
id: 2,
firstName: "David",
lastName: "Bowie"
}
]
In your controller:
.success(function(data, status) {
$scope.people = data;
});
In your HTML :
<table>
<tr>
<th>Id</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
<tr ng-repeat="person in people">
<td>{{person.id}}</td>
<td>{{person.firstName}}</td>
<td>{{person.lastName}}</td>
</tr>
</table>
Either do it yourself in the view:
<table>
<thead>
<tr>
<th>header 1</th>
<th>header 2</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in data">
<td>{{row.attribute1}}</td>
<td>{{row.attribute2}}</td>
</tr>
</tbody>
</table>
Or use a library like ui-grid to render a more advanced table.
So I have a List that I am returning from rest service. Now, I want to display this object in column format and now in row one. So it would be something like this:
firstName: Bob Alice
LastName: Doe Joe
EmailId: bob#xyz.com alice#abc.com
ContactNo: 123123 12444
So how can I use ng-repeat over here:
<tr>
<th>firstName:</th>
<td>('Name should be displayed here')</td>
</tr>
You can use ng-repeat on the td element.
<tr>
<th>firstName:</th>
<td ng-repeat="person in people">{{person.firstName}}</td>
</tr>
<tr>
<td ng-repeat="person in people">{{person.lastName}}</td>
</tr>
If you declare the keys of the objects you're iterating through, you can nest your ng-repeats so that you don't need to declare each row over and over. Do the following and nest them instead:
In the Angular App:
/*for the data*/
var personKeys = ['firstName', 'LastName', 'EmailID', 'ContactNo'];
var people = [
{
firstName: 'Bob',
LastName: 'Doe',
EmailID: 'bob#xyz.com',
ContactNo: 123123
},
/* etc */
];
/*don't forget to reference this in your controller with something like: */
this.pKeys = personKeys;
this.people = people;
In your HTML:
<table ng-controller='MyController as personList'>
<tr ng-repeat='key in personList.pKeys'>
<th>{{key}}</th>
<td ng-repeat='person in personList.people'>
{{person[key]}}
</td>
</tr>
</table>
This still has the problem of iterating over each person |attributes| times, instead of just once. I'm sure there is a clever way to only iterate once, memoize, and draw up the table without having to go through your entire data set many times, so that the runtime doesn't grow so quickly as you expand your data.