0

I set up a mock rest api with json-server and it's sitting locally for me to pull in through to demo a web app I'm working on. Here is the json:

{
  "mockData": {
    "grapevine": [
      { 
        "entity": "67.6.201.77", 
        "category": "scan", 
        "source": "emotet_tracker",
        "rscore": 42 
      },
      { 
        "entity": "67.6.201.77", 
        "category": "popular", 
        "source": "vinter",
        "rscore": 69 
      },
      { 
        "entity": "67.6.201.77", 
        "category": "spam", 
        "source": "uceprotect",
        "rscore": 48 
      },
      { 
        "entity": "67.6.201.77", 
        "category": "c2", 
        "source": "c2_validator",
        "rscore": 41 
      },
      { 
        "entity": "67.6.201.77", 
        "category": "scan", 
        "source": "greenleaf",
        "rscore": 37 
      }
    ]
  }
}

I will be specifically pulling this "grapevine" data into a table that will display on the dashboard. Right now I am getting all (5) of the entities, categories, etc... in one cell and obviously that's not formatted properly. Here is the code:

import React from 'react';
import { Table } from 'reactstrap';

export default class Example extends React.Component {

  constructor() {
    super();
    this.state = {
      people: [],
    };
  }

  componentDidMount() {
  fetch("http://localhost:3000/mockData/")
    .then(grapevine => grapevine.json())
    .then(data => this.setState({ people: data.grapevine }));
  }

  render() {
    return (
      <div className="col-md-12 bucket gv-bucket">
        <div className="card">
          <div className="card-header" id="gv-header">
            <span className="header-title">
              Grapevine&nbsp;&nbsp;&nbsp;<i class="fa fa-th-list" aria-hidden="true"></i>
            </span>
            <span className="float-right">
              <button className="btn btn-sm btn-secondary">Export Data</button>
              <a href="">
                <i className="fa fa-close close-window fa-lg"></i>
              </a>
            </span>
          </div>
          <div className="card-block">
              <Table hover bordered>
                  <thead>
                  <tr className="table-heading">
                      <th class="table-header">Entity</th>
                      <th class="table-header">Category</th>
                      <th class="table-header">Source</th>
                      <th class="table-header">Risk Score</th>
                  </tr>
                  </thead>
                  <tbody>
                  <tr>
                      <th scope="row">
                      {this.state.people.map(grapevine => (
                        <div>{grapevine.entity}</div>
                      ))}
                      </th>
                      <td></td>
                      <td></td>
                      <td></td>
                  </tr>
                  </tbody>
              </Table>
            </div>
          </div>
      </div>
    );
  }
}

If I try

                     {this.state.people.map(grapevine => (
                        <div>{grapevine.entity[0]}</div>
                      ))}

I get all five entries still but just the first letter. What am I doing wrong here? I'm obviously targeting these individual properties but I don't want all five objects displaying in the same cell.

RobiminusMaximus
  • 91
  • 1
  • 2
  • 9
  • Shouldn't it be `.then(data => this.setState({ people: data.mockData.grapevine }));`? – Blue Jan 17 '18 at 17:55
  • I get an error when I try try that – RobiminusMaximus Jan 17 '18 at 17:58
  • If one of the answers below answered your question, the way this site works works, you'd "accept" the answer, more here: ***[What should I do when someone answers my question?](http://stackoverflow.com/help/someone-answers)***. But only if your question really has been answered. If not, consider adding more details to the question. – Blue Jan 17 '18 at 18:26

3 Answers3

2

Your entire <tr> should be inside the iteration.Try

<tbody>
{this.state.people.map(grapevine => (
   <tr>
      <td>{grapevine.entity}</td>
      <td>{grapevine.category}</td>
      <td>{grapevine.source}</td>
      <td>{grapevine.rscore}</td>
   </tr>
))}
</tbody>
Prakash Sharma
  • 15,542
  • 6
  • 30
  • 37
  • Thank you so much!!!! Worked like a charm – RobiminusMaximus Jan 17 '18 at 18:00
  • If I try to add another object into mockData I get an "TypeError: Cannot read property 'map' of undefined" and points to line 16 .then(data => this.setState({ people: data.grapevine })); Do I have to change something if grapevine is no longer the only object in mockData? – RobiminusMaximus Jan 17 '18 at 19:46
0

you should be mapping and creating s, not a

{this.state.people.map(grapevine => (
    <tr>
        <td>{grapevine.entity.category}</td>
        <td>{grapevine.entity.source}</td>
    </tr>
))}
Isaiah Lee
  • 448
  • 2
  • 10
0

You need to iterate through people per table row rather than table cell:

<Table hover bordered>
  <thead>
  <tr className="table-heading">
      <th class="table-header">Entity</th>
      <th class="table-header">Category</th>
      <th class="table-header">Source</th>
      <th class="table-header">Risk Score</th>
  </tr>
  </thead>
  <tbody>
  {this.state.people.map(grapevine => (
    <tr>
      <td>{grapevine.entity}</td>
      <td>{grapevine.category}</td>
      <td>{grapevine.source}</td>
      <td>{grapevine.rscore}</td>
    </tr>
  ))}
  </tbody>
</Table>
Calvin
  • 8,697
  • 7
  • 43
  • 51