0

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: enter image description here

How can I fix this?

Appreciate the help :)

3 Answers 3

3

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
Sign up to request clarification or add additional context in comments.

9 Comments

Thanks for the quick reply. I would like to change the JSON format to a proper one but this is the best that pandas .to_json() provides for Series.. I tried out your item slicing but got this error:
ERROR in Template parse errors: Parser Error: Missing expected ) at column 42 in [{{item.key.slice(1,-1).split(', ').map((s) => s.slice(1,-1))[0]}}] in /Volumes/proj/client/src/app/analyze/analyze.component.html@45:32 (" <tr *ngFor="let item of mvaHits | keyvalue"> <td>[ERROR ->]{{item.key.slice(1,-1).split(', ').map((s) => s.slice(1,-1))[0]}}</td> <"): /Volumes/proj/client/src/app/analyze/analyze.component.html@45:32
How would I do these conversions in the .ts ?
Your browser might not support this arrow function syntax. Try this instead: {{item.key.slice(1,-1).split(', ').map(function(s) { return s.slice(1,-1) })[0]}}
turns out the way to use slice is: {{item.key | slice:1:-1}}. Also found out that split required adding a custom pipe for the angular project, documented here: stackoverflow.com/questions/43224957/…. Thanks for your help, i'll add your work plus my discoveries to the solution :)
|
0

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

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.